原文: 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>
10

javascript:

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() 就能提供视觉上的对称,以及规整程序的感觉,至少对于开发者来说更易阅读,当然代价则是由于进行了额外的调用,会有一点点性能损失。

------------------------------------------------------------------------------

jQuery之end()和pushStack()的更多相关文章

  1. 十一.jQuery源码解析之.pushStack()

    pushStack()顾明思意,就是像桟中添加东西呗,现在看看他是如何添加东西的. 创建一个空的jQuery对象,然后把Dom元素集合放入这个jQuery对象中, 并保留对当前jQuery对象的引用. ...

  2. Java程序猿的JavaScript学习笔记(8——jQuery选择器)

    计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript ...

  3. jQuery源码06-jQuery = function(){};给JQ对象,添加一些方法和属性,extend : JQ的继承方法,jQuery.extend()

    /*! * Includes Sizzle.js 选择器,独立的库 * http://sizzlejs.com/ */ (function( window, undefined ) { //" ...

  4. jquery js解析函数、函数直接调用

    ----------------------------------------------------------------- cc = function(){alert(345)}, pushS ...

  5. jqu

    1 /*2 * 说明:3 * 本源代码的中文注释乃Auscarlin呕心沥血所作.旨在促进jQuery的传播以及向广大jQuery爱好者提供一个进阶4 *的途径,以让各位更加深入地了解jQuery,学 ...

  6. jquery2.0.3 全部源码

    /*! * Includes Sizzle.js 选择器,独立的库 * http://sizzlejs.com/ */ (function( window, undefined ) { //" ...

  7. jQuery 2.0.3 源码分析 回溯魔法 end()和pushStack()

    了解了jQuery对DOM进行遍历背后的工作机制,可以在编写代码时有意识地避免一些不必要的重复操作,从而提升代码的性能 从这章开始慢慢插入jQuery内部一系列工具方法的实现 关于jQuery对象的包 ...

  8. jQuery原型方法.pushStack源码分析

    这次分析的方法跟前面不同,虽然pushStack也是原型方法之一,但是我们几乎从不用在页面调用,在参考手册里面也没有这个方法的使用说明,但是这个方法还是非常重要的,在使用很多jQuery的其他方式都会 ...

  9. jquery源码解析:pushStack,end,ready,eq详解

    上一篇主要讲解了jQuery原型中最重要的方法init.接下来再讲一些比较常用的原型方法和属性 core_slice = [].slice, jQuery.fn = jQuery.prototype ...

随机推荐

  1. Ubuntu16.04中nginx除80之外其他端口不能访问

    不废话, 大多数都以为是ufw防火墙的问题. 但我的是因iptables防火墙, 坑死我了. 查了好多也没查到怎么在Ubuntu关闭iptables, 索性直接卸载 apt-get remove ip ...

  2. 舞蹈链 DLX

    欢迎访问——该文出处-博客园-zhouzhendong 去博客园看该文章--传送门 舞蹈链是一个非常玄学的东西…… 问题模型 精确覆盖问题:在一个01矩阵中,是否可以选出一些行的集合,使得在这些行的集 ...

  3. Trident中的过滤与函数的区别

    1.共同点 都需要实现storm.trident.operation.Function接口 2.不同点 其中函数有发射这个步骤. .each(new Fields("orderTime&qu ...

  4. SSL/TLS

    為 授权计算机为 SSL/TLS 安全通道建立信任关系. ServicePointManager.ServerCertificateValidationCallback += (o, c, ch, e ...

  5. css3 webkit-box的用法

    webkit-box 1.之前要实现横列的web布局,通常就是float或者display:inline-block; 但是都不能做到真正的流体布局.至少width要自己去算百分比.2.flexibl ...

  6. 【LeetCode算法-9】Palindrome Number

    LeetCode第9题 Determine whether an integer is a palindrome. An integer is a palindrome when it reads t ...

  7. LightOJ 1074 - Extended Traffic 【SPFA】(经典)

    <题目链接> 题目大意:有n个城市,每一个城市有一个拥挤度Ai,从一个城市I到另一个城市J的时间为:(A(v)-A(u))^3.问从第一个城市到达第k个城市所花的时间,如果不能到达,或者时 ...

  8. Farewell Party-构造

    Farewell Party 思路 : 转换思路 ,有 a [ i ] 个不相等的 ,那么至少得有 n - a [ i ]个与它相等的. 但是有可能与它拥有相同数目的有很多. 但是为了能够最终 分配成 ...

  9. VeeamBackup9.5安装与配置

    产品介绍 Veeam是一家第三方的虚拟化数据中心备份及恢复公司,主要软件为Veeam Availability Suite,包括Veeam Backup & Replication和Veeam ...

  10. javascript事件绑定和普通事件的区别

    <!doctype html><html lang="en"><head> <meta charset="UTF-8" ...