現在Jquery框架對於開發人員基本上是無人不知,無人不曉了,用起來十分的方便,特別是選擇器十分強大,提高了我們的開發速度。但是好多人也只是停留在了會用的基礎上,我個人覺得會用一個框架不算什么,只能說明你對那個框架比較熟悉,知道里面的思想和實現才是王道。有好多大牛對Jquery框架進行了剖析,今天我只是根據我的見解來分析一下。
一段代碼如下:
(function (win) { var _$ = function (selector, context) { return new _$.prototype.Init(selector, context); } _$.prototype = { Init: function (selector, context) { this.elements = []; var context = context || document; if (context.querySelectorAll) { var arr = context.querySelectorAll(selector); for (var i = 0; i < arr.length; i++) { this.elements.push(arr[i]); } }
////這一塊是選擇器的實現,沒有寫完,可以自己實現 }, each: function (callback) { if (this.elements.length > 0) { for (var i = 0; i < this.elements.length; i++) { callback.call(this, i, this.elements[i]); } } } } _$.prototype.Init.prototype = _$.prototype; window.$ = _$; })(window || global);
一般的我們寫一個函數,調用的方法如下:
var Demo=function(){
}
Demo.prototype= {
method:function(){
}
}
var demo=new Demo();//實例化Demo
之后我們可以調用method方法:
demo.method();
如果這樣的話,我們每次都要實例化一下,才能調用里面的方法,豈不是有點兒煩?
我想直接這樣調用:Demo().method();這樣不是省了一段代碼(哈哈,程序員都喜歡偷懶)。
那么我們再寫一段代碼:
var demo=function(){
return new Demo();
}
然后就可以demo().method()這樣調用了。
如果你理解了我講的這個,相信下面的代碼你就會明白了:
var _$ = function (selector, context) { return new _$.prototype.Init(selector, context); }
接下來我們再看看_$.prototype.Init方法的擴展
Init: function (selector, context) { this.elements = []; var context = context || document; if (context.querySelectorAll) { var arr = context.querySelectorAll(selector); for (var i = 0; i < arr.length; i++) { this.elements.push(arr[i]); } }
////這一塊是選擇器的實現,沒有寫完,可以自己實現 }
這里面有selector,context兩個參數:
selector其實就是所謂的選擇器符號了,我們是根據這個來找到dom節點對象的。
context就是我們所說的執行上下文了,通常都是document,這個是可選參數,只是為了以后的擴展。
然后我們要獲取節點對象了
var arr = context.querySelectorAll(selector);
document.querySelector和document.querySelectorAll是w3c標准新加入的方法 ,是已經寫好的選擇器,但是ie8以下的版本不支持。
我們要優先查看有沒有這個方法,有的話就直接用這個了。
沒有就直接用document.getElementById, document.getElementsByClassName(IE8以下不兼容,須擴展), document.getElementsByName,document.getElementsByTagName擴展了
(這個后面會講具體實現)。
this.elements=[]保存查詢出的dom節點對象。
然后說說each方法,這個其實是用回掉簡化 elements的循環。
each: function (callback) { if (this.elements.length > 0) { for (var i = 0; i < this.elements.length; i++) { callback.call(this, i, this.elements[i]); } } }
這些方法我們都實現了,但是有一個問題:怎么讓Init方法的this.elements這個屬性讓$也能共享呢?他們的作用域不一樣呢。
var _$ = function (selector, context) { return new _$.prototype.Init(selector, context); }
我們最終得想法其實是想用$().method()這種方式去對dom節點做事件綁定,動畫效果,樣式設置等等處理。
我們知道:如果讓兩個對象共享一個屬性,那么有一個方法就是讓他們的原型指向一致
那么,關鍵的一段代碼上場了:
_$.prototype.Init.prototype = _$.prototype;
這樣之后我們就可以讓_$和Init實現對elements的共享了。
Jquery框架的核心代碼其實就是這些了。后面就可以對$進行方法擴展了。
今天就講到這,有些說法不是很規范,但是應該能看懂,后面會陸續講各個方法的具體實現。。。