做爲一名常年奮戰在java世界中的程序猿,當我接觸到如今所謂的前端技術時,心裏實際上是崩潰的。由於,前端的技術給個人第一個感受就是「亂」,這裏充斥着各類框架、插件和樣式,每每因爲版本和引入順序等問題,形成不可描述的問題,輕者引起錯誤,沒法實現效果;重者頁面崩潰,分崩離析。javascript
然而,前端技術做爲一個web的重要部分,在整個系統中是不可或缺的,若是你要問我係統運行中比較前端和後端哪一個更重要,我會堅決果斷的說是前端。由於,從後端的角度看,如今的系統大都是與數據庫打交道,將數據持久化,而後經過各類組合查詢、計算,將數據提交給前端展示,這個過程都是可控的;而前端面對用戶的使用,用戶的操做實際上是很複雜的,對用戶的交互每每存在不少不肯定性。因此,從這個角度看來,前端其實更加的難於處理和實現。固然若是您是作系統底層,使用大量複雜的數學算法,實現高效的系統功能,前面對於前端和後端的評價就當我沒說,這種開發工做和開發者也是我最爲欽佩的。css
至於寫這篇文章的目的,實際上是做爲我的接觸前端的一個記錄。前端的技術涵蓋的範圍是在不少、很雜,我平常的工做中接觸最多的仍是偏向管理系統的開發工做,因此前端技術更多偏向於使用JavaScript來實現頁面的各類功能。而管理系統中最多見的就是表格,各種數據都要在表格中展示。看了一些頁面的例子,經常會用到DataTables這個插件,我也試了試在頁面中使用,效果不錯。但做爲一名有追求的程序猿,怎麼能知足於只是簡單對插件的使用層面呢!我想了解這樣的插件是怎麼實現的,並且能不能本身完成一個相似的插件,去掉一些不須要的功能,增長一些更貼近本身的需求的功能,這想來是極好的。不過,做爲一個剛剛接觸前端的小白,分析一個插件確實也是一件很是困難的事情,可是我想若是把這個插件分析完成,想來對於前端的JavaScript相關技術也會有一個長足的進步吧。html
下面就開始個人探索之旅,可能會用很長時間來完成哦。前端
首先,我須要準備一個DataTables的插件源碼和測試環境,插件是從官網下載的https://www.datatables.net/,另外還須要jQuery,就能夠完成最基本的表格了。java
<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
這裏,只有一個jquery.dataTables.js文件須要研究,打開這個文件,拉到文檔末尾
web
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 ) { ... }
接下來,咱們會繼續深刻分析這個函數,以及相關的內容。