大多數(shù)jQueryDOM遍歷方法來操作jQuery對象實例,并創(chuàng)建一個新的對象,匹配一個不同的DOM元素集合。當發(fā)生這種情況時,實際上是新的元素集合被壓入到對象內(nèi)部維護的棧中。每次過濾方法都會被壓入棧中。當我們需要返回到前一個狀態(tài)時,我們可以使用end()進行出棧操作,來返回棧中的前一個狀態(tài)。
假設頁面上有幾個列表項:右圖所示
end()方法主要用于jQuery的鏈式屬性中。當沒有使用鏈式用法時,我們通常只是調(diào)用變量名上的前一個對象,所以我們不需要操作棧。
使用end()時,我們可以一次性調(diào)用所有需要的方法:
$('ul.first').find('.foo').css('background-color', 'red').end().find('.bar').css('background-color', 'green');
鏈式的原理就是要返回當前操作的上下文。
下面的代碼是錯誤的:
$('ul.first').find('.foo').css('background-color', 'red').find('.bar').css('background-color', 'green');
上面的代碼因為上下文被切換了,所以執(zhí)行find(‘bar’)時就出錯了。
下面的代碼是正確的寫法:
$('ul.first').find('.foo').css('background-color', 'red').end().find('.bar').css('background-color', 'green');
首先在鏈式用法中只在第一個列表中查找樣式為 foo 的項目,并將其背景色變成紅色。然后end()返回調(diào)用find()之前的狀態(tài)。因此,第二次 find() 將只會查找 <ul class="first"> 中的 '.bar',而不是繼續(xù)在<li class="foo">中進行查找,結果是將匹配到的元素的背景色變成綠色。上述代碼的最終結果是:第一個列表中的第 1 和第 3 個列表項的背景色有顏色,而第二個列表中的任何項目都沒有背景色。
總的來說:end方法就是回溯到上一個Dom合集,因此對于鏈式操作與優(yōu)化,這個方法還是很有意義的。
源碼實現(xiàn)
既然是回溯到上一個DOM合集,那么肯定end方法中返回的就是一個jQuery對象了,所以我們看源碼其實就是返回prevObject對象了,如下代碼:
end: function() {
return this.prevObject || this.constructor(null);
}
prevObject在什么情況下會產(chǎn)生?
在構建jQuery對象的時候,通過pushStack方法構建,如下代碼:
jQuery.fn.extend({ find: function(selector) { //...........................省略................................ //通過sizzle選擇器,返回結果集 jQuery.find(selector, self[i], ret); // Needed because $( selector, context ) becomes $( context ).find( selector ) ret = this.pushStack(len > 1 ? jQuery.unique(ret) : ret); ret.selector = this.selector ? this.selector + " " + selector : selector; return ret; } }
可以看到通過jQuery.find后得到了結果ret這個就是通過純的DOM節(jié)點,那么如果變成一個jQuery對象呢?
接著我們看pushStack對象,作用就通過新的DOM元素去創(chuàng)建一個新的jQuery對象
pushStack: function( elems ) { // Build a new jQuery matched element set var ret = jQuery.merge( this.constructor(), elems ); // Add the old object onto the stack (as a reference) ret.prevObject = this; ret.context = this.context; // Return the newly-formed element set return ret; }
流程解析:
1、首先構建一個新的jQuery對象,因為constructor是指向構造器的,所以這里就等同于調(diào)用jQuery()方法了,返回了一個新的jQuery對象;
2、然后用jQuery.merge語句把elems節(jié)點合并到新的jQuery對象上;
3、最后給返回的新jQuery對象添加prevObject屬性,我們看到prevObject其實還是當前jQuery的一個引用罷了,所以也就是為什么通過prevObject能取到上一個合集的原因了。
請驗證,完成請求
由于請求次數(shù)過多,請先驗證,完成再次請求
打開微信掃碼自動綁定
綁定后可得到
使用 Ctrl+D 可將課程添加到書簽
舉報