jquery學習筆記 美元背後的一點小技巧

2021-09-06 14:45:31 字數 3580 閱讀 7846

寫在前面:本文比較基礎,僅是一枚菜鳥接觸jquery過程中的一點思考和總結,內容較基礎,希望能對剛接觸jquery的童鞋有一點幫助 :)

按照國際慣例(其實就是俺寫作的習慣),首先丟擲待問題的場景。至於問題的答案,文章並不會急著揭曉,而是通過逐層遞進的方式,展現思考、解決乙個問題的過程

考慮下面乙個場景,假設我們頁面上有個id為casper的div標籤,如下所示

<

div

id="casper"

class

="hello"

>casper是個大傻瓜,啦啦啦啦啦

div>

現在我們想要給它新增乙個class,比如「world」,用jquery的話如何實現?很簡單,不賣關子

$('#casper').addclass('world');

很好,接下來我們思考:如何不用jquery,我們如何如何實現實現上述功能?最簡單的方式:

var node = document.getelementbyid('casper');

node.classname += ' world';

getelementbyid、getelementsbytagname神馬的,名字老長老長的,寫著有點不爽,於是把getelementbyid這個方法用美元($)包裝下:

function

$(id)

$('casper').classname += ' world';

classname品字串神馬的,jquery的呼叫方式相比麻煩多了,那再改進下:

function

$(id);

return

document.getelementbyid(id);

}$('casper').addclass('world');

看上去挺像那麼一回事了,多優雅的介面啊(熱淚盈眶中)~

真的是這樣嗎,再仔細瞧瞧?於是果斷發現不對勁的地方:對於$,每次呼叫,都會給返回的dom元素上新增乙個addclass方法,這對空間來說是極大的浪費。當然,可以將addclass方法抽取出來:

function

addclass(classname)

function

$(id)

$('casper').addclass('world');

原先的空間浪費問題可以在很大程度上得到解決,但明顯這解決方法還不夠好。如果有那麼一種實現方式,讓所有的物件例項都共享乙個方法。。。

同樣不必賣關子,這裡說的就是原型方法,我們再看下jquery的呼叫方式

$('#casper').addclass('world');

$('#casper')並不是像我們上面那樣,簡單地將id為casper的元素返回。實際上,$('#casper')返回的是乙個jquery物件,該物件特徵如下:

擁有乙個length屬性,length等於你呼叫$選中的元素的數目,在$('#casper')中為1

擁有0~n-1的例項屬性,分別對應呼叫$時選中的第1~第n個元素,如本例中$('#casper')[0]即為目標dom元素

擁有一堆原型方法,如常見的addclass、removeclass、bind等

根據上面三點,很容易對我們之前寫的**進行修改,如下:

function

$(id)

$.prototype.addclass = function

(classname);

var noode = new $('casper');

node.addclass('world');

其實就幾行**的事情,但。。。還是覺得有些不對勁,new $('casper'),平常在用jquery的時候似乎不需要new一下的說,想想看,我們**中一坨new是多麼可怕的事情~

好吧,其實是因為jquery幫你完成了構造函式呼叫的這部分工作,這一小小的細節改善對jquery的流行起到了很大的幫助。按照這個思路,繼續修改之前的**:

function

$(id)

//其他一樣,節省空間不貼**

在上面的**中,只有一點小小的修改,就是加了個判斷語句 if(!(this instanceof $)) ,作用在於判斷,當$被呼叫時,究竟是採用以下兩種呼叫方式的哪一種,關於這種判斷方式,可參考之前寫的《【經驗總結】建構函式的強制呼叫》:

$('casper'),直接呼叫,於是this為window

new $('casper'),此時$為構造方法,this instanceof $ == true

羅嗦了這麼多,我們看看關於這點,jquery裡是如何實現的,原始碼大致如下,一些不相干的**略過:

(function

( window, undefined ) ,

//一堆無關細節暫時略過

jquery.fn = jquery.prototype =

};//give the init function the jquery prototype for later instantiation

jquery.fn.init.prototype =jquery.fn;

return

jquery;

})();

window.jquery = window.$ =jquery;

})( window );

對於研究過jquery原始碼或曾經打算研究jquery原始碼的同學來說,上面這段**肯定不會陌生,它有乙個特點:看上去比較晦澀,特別是是結合了jquery原始碼裡面比較詭異的**縮排~

通過閉包返回的jquery物件,閉包裡面是有jquery函式定義,jquery函式裡面return了new jquery.fn.init 。。。快速看懂上面這段**的秘訣在於:乙個支援**高亮和職能中括號匹配的編輯器,比如webstorm。。。

上面只是開個小玩笑,繞了這麼久,無法是想做下面幾件事情:

無論有沒有new,只要呼叫$,都給你返回乙個jquery物件(實際上jquery.fn.init才是實際的建構函式)

將jquery.fn.init.fn指向jquery.prototype,這樣的話,當我們通過$.fn.newprototypeattr 方式向jquery新增原型屬性或方法,其實最終都成為了jquery.fn.init地原型屬性或方法

將constructor屬性指向jquery,不然$('#casper').constructor 獲得的會是jquery.fn.init

個人覺得上面這段**有些費解,似乎完全可以採用相對不那麼曲折的方式實現,如下所示,其實思路都是相同的:

然後,就是新增各種原型方法了,相容性處理和優雅的api,這塊才是精華,這裡還沒講到。

(function

();

var _jquery = function

(id);

jquery.fn = jquery.prototype =

};_jquery.prototype =jquery.fn;

window.$ = window.jquery =jquery;

})();

學習筆記 jquery的this

this,表示當前的上下文物件是乙個html物件,可以呼叫html物件所擁有的屬性,方法 this 代表的上下文物件是乙個jquery的上下文物件,可以呼叫jquery的方法和屬性值。jquery中this與 this 的區別 textbox hover function fucntion 這裡的t...

jquery學習筆記

判斷checkbox是否被選中if attr checked true 檢查元素是否存在 if tt length 0 if tt 0 檢查元素是否隱藏 alert dvtest is visible 判斷元素顯示或隱藏狀態 多選框操作 獲取一組radio被選中項的值 var item input ...

Jquery 學習筆記

text 和 val 的區別 text 方法是取得所有匹配元素的內容。結果是由所有匹配元素包含的文字內容組合起來的文字。這個方法對html和xml文件都有效。獲取span,div p之類才用text 或html 方法。例子 b a p text 將得到 ba 單行文字不能用text 方法獲得值,必須...