jQuery之end()和pushStack()
原文:?https://www.cnblogs.com/AndyWithPassion/archive/2012/02/06/jquery_pushStack_javascript.html
jquery.fn.end()方法, pushStack()
jQuery之end()和pushStack()
pushStack()方法在jQuery的DOM操作中被頻繁的使用, 如在parent(), find(), filter()中, 當然還有其他許多類似的方法, 它們往往需要返回一個jQuery封裝過的DOM結果集.但在我們自己寫jQuery代碼的時候,卻很少關注或使用過pushStack(). 如果我們需要寫個涉及DOM遍歷的插件,它就會顯得尤其有用.
在jQuery內部,pushStack()方法通過改變一個jQuery對象的prevObject屬性來"跟蹤"鏈式調用中前一個方法返回的DOM結果集(被jQuery封裝過,也是個jQuery對象,說是"跟蹤",是因為實際存儲的是個引用). 當我們再鏈式調用end()方法后, 內部就返回當前jQuery對象的prevObject. 具體更多細節, 直接看源碼即可. 這里只做個簡單的分析, 直接來個例子:
html:
1 <div id="grandparent">2 I am grandparent.3 <div id="parent">4 I am parent.5 <div id="child">6 I am child.7 </div>8 </div>9 </div> 10javascript:
1 var els = $('#child').parent().parent(); 2 console.dir(els);圖解:
了解這個之后, 我們來做一個grandparent插件,用來替代.parent().parent()這樣連續2次的調用,直接用.grandparent().如果"一不小心"沒考慮end()的話,代碼很可能就是這個樣子的:
| $.fn.grandparent = function() { ????return?this.parent().parent(); }; |
依舊用上面那個例子:
| 1 | $('#child').grandparent().end();?//jQuery-[div#parent] |
很顯然, 大多數情況下這不是我們想要的, 事實上我們想通過鏈式調用end()直接返回到jquery[div#child]. 現在該是pushStack出馬的時候了,我們只要加上一行即可:
| 1 2 3 4 | $.fn.grandparent =?function() { ????var?els =?this.parent().parent(); ????return?this.pushStack(els.get()); }; |
在pushStack內部, 把els.get()返回的DOM數組封裝成一個新的jQuery對象, 而this(jQuery[div#child])會賦值給之前新構建jQuery的prevObject, 最后返回新生的那個jQuery對象.
所以這次, 當我們再用end()就對了:
| var?grandparent = $('#child').grandparent()./* jquery-[div#grandparent]*/.end() /*jquery-[div#child]*/ |
此博文內容的主體思想來自Learning JQuery中的一篇博客, 感謝該作者的分享. 感興趣的話, 點擊jQuery pushStack.
------------------------------------------------------------------------------------------------------------
end() 方法結束當前鏈條中的最近的篩選操作,并將匹配元素集還原為之前的狀態。
語法
.end()詳細說明
大多數 jQuery 的遍歷方法會操作一個 jQuery 對象實例,并生成一個匹配不同 DOM 元素集的新對象。當發生這種情況時,應該會把新的元素集推入維持在對象中的堆棧內。每次成功的篩選方法調用都會把新元素推入堆棧中。如果我們需要老的元素集,可以使用 end() 從堆棧中彈出新集合。
假設頁面中有一對很短的列表:
<ul class="first"><li class="foo">list item 1</li><li>list item 2</li><li class="bar">list item 3</li> </ul> <ul class="second"><li class="foo">list item 1</li><li>list item 2</li><li class="bar">list item 3</li> </ul>例子 1
主要是在利用 jQuery 的鏈條屬性(命令鏈)時,jQuery 會比較有用。如果不使用命令鏈,我們一般是通過變量名來調用之前的對象,這樣我們就不需要操作堆棧了。不過通過 end(),我們可以把所有方法調用串聯在一起:
$('ul.first').find('.foo').css('background-color', 'red').end().find('.bar').css('background-color', 'green');親自試一試
這條命令鏈檢索第一個列表中類名為 foo 的項目,并把它們的背景設置為紅色。end() 會將對象還原為調用 find() 之前的狀態,所以第二個 find() 查找的是 <ul class="first"> 內的 '.bar' ,而不是在列表的 <li class="foo"> 中查找,并將匹配元素的背景設置為綠色。最后的結果是第一個列表中的項目 1 和項目 3 被設置了帶顏色的背景,而第二個列表中的項目沒有任何變化。
例子 2
這條長長的 jQuery 鏈可以可視化為結構化的代碼塊,篩選方法打開嵌套代碼塊,而 end() 方法用來關閉代碼塊:
$('ul.first').find('.foo').css('background-color', 'red') .end().find('.bar').css('background-color', 'green') .end();親自試一試
最后這個 end() 不是必需的,因為我們隨后會丟棄這個 jQuery 對象。不過,如果按照這種形式編寫代碼,end() 就能提供視覺上的對稱,以及規整程序的感覺,至少對于開發者來說更易閱讀,當然代價則是由于進行了額外的調用,會有一點點性能損失。
------------------------------------------------------------------------------
轉載于:https://www.cnblogs.com/oxspirt/p/10780436.html
總結
以上是生活随笔為你收集整理的jQuery之end()和pushStack()的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: js 格式化带时区的日期
- 下一篇: Promise的源码实现(完美符合Pro