DataTables源码分析

写在前面

作为一名常年奋战在java世界中的程序猿,当我接触到现在所谓的前端技术时,内心其实是崩溃的。因为,前端的技术给我的第一个感觉就是“乱”,这里充斥着各种框架、插件和样式,往往由于版本和引入顺序等问题,造成不可描述的问题,轻者引发错误,无法实现效果;重者页面崩溃,分崩离析。

然而,前端技术作为一个web的重要部分,在整个系统中是不可或缺的,如果你要问我系统运行中比较前端和后端哪个更重要,我会毫不犹豫的说是前端。因为,从后端的角度看,现在的系统大都是与数据库打交道,将数据持久化,然后通过各种组合查询、计算,将数据提交给前端展现,这个过程都是可控的;而前端面对用户的使用,用户的操作其实是很复杂的,对用户的交互往往存在很多不确定性。所以,从这个角度看来,前端其实更加的难于处理和实现。当然如果您是做系统底层,使用大量复杂的数学算法,实现高效的系统功能,前面对于前端和后端的评价就当我没说,这种开发工作和开发者也是我最为钦佩的。

至于写这篇文章的目的,其实是作为个人接触前端的一个记录。前端的技术涵盖的范围是在很多、很杂,我日常的工作中接触最多的还是偏向管理系统的开发工作,所以前端技术更多偏向于使用JavaScript来实现页面的各种功能。而管理系统中最常见的就是表格,各类数据都要在表格中展现。看了一些页面的例子,常常会用到DataTables这个插件,我也试了试在页面中使用,效果不错。但作为一名有追求的程序猿,怎么能满足于只是简单对插件的使用层面呢!我想了解这样的插件是怎么实现的,而且能不能自己完成一个类似的插件,去掉一些不需要的功能,增加一些更贴近自己的需求的功能,这想来是极好的。不过,作为一个刚刚接触前端的小白,分析一个插件确实也是一件非常困难的事情,但是我想如果把这个插件分析完成,想来对于前端的JavaScript相关技术也会有一个长足的进步吧。

下面就开始我的探索之旅,可能会用很长时间来完成哦。

插件的实现

首先,我需要准备一个DataTables的插件源码和测试环境,插件是从官网下载的https://www.datatables.net/,另外还需要jQuery,就可以完成最基本的表格了。

<head>
  <meta charset="utf-8">
  <title></title>
  <link rel="stylesheet" href="../stylesheet/css/jquery.dataTables.css">
</head>
<body>
  <table id="example" class="display" cellspacing="0" width="100%">
.
.
.
  </table>

  <script src="../js/jquery-3.1.1.js" charset="utf-8"></script>
  <script src="../js/jquery.dataTables.js" charset="utf-8"></script>
  <script type="text/javascript">
    $(document).ready(function() {
       $('#example').dataTable();
    });
  </script>
</body>

可以看到,只要简单的引入jquery.dataTables.css样式和jquery-3.1.1.js、jquery.dataTables.js两个js文件,然后调用一下$('#example').dataTable();方法,就搞定了一个表格,把页面的table,变成了一个比较漂亮的,支持排序、搜索等功能的表格了。这个表格是dataTables官方例子的最简单的零配置的例子,效果如下:

这里,只有一个jquery.dataTables.js文件需要研究,打开这个文件,拉到文档末尾

1万5千多行代码!容我看一眼99年的asp压压惊,那时候天是那样的蓝,空气也是那样的清新,代码也没有这么长......

好吧,是我想多了,什么时候代码都是很长的,还是研究一下代码吧,大体看一下,整个代码分成了两个部分:

(
  fuction(factory){  //函数一
    ...
  }
  (function($, window, document, undefined){ 函数二
    ...
  })
);

函数一其实并不长,只是判断了三种情况对函数二的调用,一个是遵循AMD标准的,一个是CommonJS的,还有其他的情况。AMD和CommonJS就不展开研究了,之前看过以为大哥写的对于datatables不支持requireJS的解决办法,应该那个时候datatables对AMD规范还不支持,现在看来已经可以支持了,不需要自己在requireJS环境中手工调用了。函数一应该是datatables后来增加的一个小帽,用来支持不同的情况对下面函数二的调用,而函数二才是整个插件的主体,全部的关于插件的代码也都在函数二中完成。函数一在页面加载后会直接调用,函数二不会直接调用,但是会被函数一通过factory调用:

factory( jQuery, window, document );

我们顺着这个最简单的例子的调用来分析,这个例子中只是通过jQuery的选择器,得到了页面上table的对象,之后调用对象的dataTable();方法,就实现了表格的加载。

这里的有一个问题,就是页面的对象本身是没有dataTable方法的,这个方法是怎么加载到table对象上的呢?我们去看函数二,在函数的末尾有这样几句话:

```

// jQuery access

$.fn.dataTable = DataTable;

// Provide access to the host jQuery object (circular reference)
DataTable.$ = $;

// Legacy aliases
$.fn.dataTableSettings = DataTable.settings;
$.fn.dataTableExt = DataTable.ext;

// With a capital `D` we return a DataTables API instance rather than a
// jQuery object
$.fn.DataTable = function ( opts ) {
    console.log('1111');
    return $(this).dataTable( opts ).api();
};

```

$.fn.dataTable = DataTable;这句是向jQuery增加了一个函数,这个函数的函数名叫做dataTable,看看这不就是上面在table对象上调用的函数吗!这里要注意,$('#example'),得到的是一个jQuery对象,而不是html的页面元素,通过这个我猜测所有的选择器得到的对象,应该都继承自jQuery对象,这样就可以使用jQuery对象的方法了。

查了一下$.fn其实就等同于jQuery.prototype,也就是说dataTable函数被定义到了jQuery的原型中,所有继承自jQuery的对象,都可以使用这个函数。关于原型的概念,请自行百度或者参考《JavaScript高级程序设计》,这本书中有非常详细的描述(当然,其他书中也有,我是看的这本书了解的)。以后有时间会针对原型单独写一篇文章来介绍这个JavaScript中最奇怪的对象。

到这里,我们基本了解了插件的触发过程,我们如果要自定义一个插件,也可以做类似的实现,就是把一个函数定义到$.fn中,之后页面上通过jQuery得到元素,并调用我们自定义的方法,就可以对这个元素进行操作,也就完成了一个插件的最基本的定义。

$.fn.dataTable = DataTable;一句把dataTable函数指向了DataTable,而DataTable是这个js中定义的一个函数:

var DataTable = function ( options ) { ... }

接下来,我们会继续深入分析这个函数,以及相关的内容。

DataTables源码分析(一)的更多相关文章

  1. DataTable源码分析(二)

    DataTable源码分析(二) ===================== DataTable函数分析 ---------------- DataTable作为整个插件的入口,完成了整个表格的数据初 ...

  2. ABP源码分析一:整体项目结构及目录

    ABP是一套非常优秀的web应用程序架构,适合用来搭建集中式架构的web应用程序. 整个Abp的Infrastructure是以Abp这个package为核心模块(core)+15个模块(module ...

  3. HashMap与TreeMap源码分析

    1. 引言     在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...

  4. nginx源码分析之网络初始化

    nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解,本文主要通过nginx的源代码来分析其网络初始化. 从配置文件中读取初始化信息 与网 ...

  5. zookeeper源码分析之五服务端(集群leader)处理请求流程

    leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...

  6. zookeeper源码分析之四服务端(单机)处理请求流程

    上文: zookeeper源码分析之一服务端启动过程 中,我们介绍了zookeeper服务器的启动过程,其中单机是ZookeeperServer启动,集群使用QuorumPeer启动,那么这次我们分析 ...

  7. zookeeper源码分析之三客户端发送请求流程

    znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的 ...

  8. java使用websocket,并且获取HttpSession,源码分析

    转载请在页首注明作者与出处 http://www.cnblogs.com/zhuxiaojie/p/6238826.html 一:本文使用范围 此文不仅仅局限于spring boot,普通的sprin ...

  9. ABP源码分析二:ABP中配置的注册和初始化

    一般来说,ASP.NET Web应用程序的第一个执行的方法是Global.asax下定义的Start方法.执行这个方法前HttpApplication 实例必须存在,也就是说其构造函数的执行必然是完成 ...

随机推荐

  1. [翻译]现代java开发指南 第二部分

    现代java开发指南 第二部分 第二部分:部署.监控 & 管理,性能分析和基准测试 第一部分,第二部分 =================== 欢迎来到现代 Java 开发指南第二部分.在第一 ...

  2. JAVA 在程序中存储和修改信息

    1.语句和表达式 计算机程序是一组告诉计算机什么的指令,每一个指令称为语句. 2.指定变量类型 变量名.变量存储的信息类型 整型int(-2.14*109~2.14*109).浮点型float(38位 ...

  3. 每天一个Linux命令(16)--which命令

    把昨天的,留给昨天:今日,你将重新开始. 好的,在第一个阶段我们学习了  文件目录的操作命令: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ls cd pwd mkdir ...

  4. Laravel路由

    Laravel安装,这里使用一键安装包. 使用PHP内置的Web服务器,在PHP文件夹下运行命令行 php -S 0.0.0.0:1024 一.设置路由 路由文件在app\HTTP\routes.ph ...

  5. 联网html引用BootStrap

    以下是我写的一个联网html引用BootStrap的例子,可作为参考: <%@ Page Language="C#" AutoEventWireup="true&q ...

  6. Maven 使用笔记

    一:手动添加包进本地仓库 Maven 安装 JAR 包的命令是: mvn install:install-file -Dfile=jar包的位置 -DgroupId=[groupId] -Dartif ...

  7. RxSwift 入坑好多天 - 终于有了一点理解

    一.前言 江湖上都在说现在就要赶紧学 swift 了,即将是 swift 的天下了.在 api 变化不大的情况下,swift 作为一门新的语言,集众家之所长,普通编码确实比 oc 要好用的多了 老早就 ...

  8. [LeetCode]Rotate Image(矩阵旋转)

    48. Rotate Image     Total Accepted: 69437 Total Submissions: 198781 Difficulty: Medium You are give ...

  9. ajax 实现三级联动

    ajax 实现三级联动,相当于写了一个小插件,用的时候直接拿过来用就可以了,这里我用了数据库中的chinastates表, 数据库内容很多,三级联动里的地区名称都在里面,采用的是代号副代号的方式 比如 ...

  10. (102, "Incorrect syntax near '-'.DB-Lib error message 102, severity 15:\nGen

    python 调用MSSQL存储过程,运行时报错 sql="exec spname %s,%s"%(param1,param2) 这是错误的调用存储过程的语句,param1和par ...