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

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

  • 相关阅读:
    HDU5000 (DP + 规律)
    HDU5127 神坑题---vector 、 list 、 deque 的用法区别
    HDU5128 细心、细心、细心
    dij单源最短路纯模板
    POJ 1236 SCC+缩点
    SCC(强连通分量)
    用树状数组求数组内的逆序对数
    HDU 1811 并查集
    大数模板,只要不是手敲,非常好用
    市赛
  • 原文地址:https://www.cnblogs.com/oxspirt/p/10780436.html
Copyright © 2011-2022 走看看