【问题标题】:jQuery - suggestions for a "nextWhile" traversion?jQuery - 关于“nextWhile”遍历的建议?
【发布时间】:2010-10-07 04:07:52
【问题描述】:

jQuery 目前有 .next(filter).nextAll(filter) 但我需要一些适合它们中间的东西 - 实际上是一个 .nextWhile(filter) 重复执行下一步直到过滤器不再为真,然后停止(而不是继续结束)。

为了证明这一点,下面是一些简化的 HTML——(实际上,它是动态生成的、随机顺序/数据、更多列、正确的类名等等)。

<table>
    <thead>
        <tr>
            <th>...</th>
        </tr>
    </thead>
    <tbody>

        <tr class="x"><td>a <button>Show/Hide</button></td></tr>
            <tr class="x y"><td>a1</td></tr>
            <tr class="x y"><td>a2</td></tr>

        <tr class="z"><td>b</td></tr>

        <tr class="z"><td>c</td></tr>

        <tr class="x"><td>d <button>Show/Hide</button></td></tr>
            <tr class="x y"><td>d1</td></tr>
            <tr class="x y"><td>d2</td></tr>
            <tr class="x y"><td>d3</td></tr>

        <tr class="z"><td>e</td></tr>

        <tr class="x"><td>f</td></tr>

        <tr class="x"><td>g <button>Show/Hide</button></td></tr>
            <tr class="x y"><td>g1</td></tr>
            <tr class="x y"><td>g2</td></tr>

    </tbody>
</table>

针对此运行一些 JavaScript:

<script type="text/javascript">
    var $j = jQuery.noConflict();

    $j().ready(init);

    function init()
    {
        $j('tr.y').hide();
        $j('tr.x button').click( toggleRelated );
    }

    function toggleRelated()
    {
        // Only toggles one row
        // $j(this).parents('tr').next('.y').toggle();

        // Toggles unrelated ones also
        $j(this).parents('tr').nextAll('.y').toggle();

        // Not currently a jQuery construct
        // $j(this).parents('tr').nextWhile('.y').toggle();
    }

</script>

有没有简单的方法来实现这个nextWhile 构造?

理想情况下,这需要在不修改当前 HTML 的情况下实现。

【问题讨论】:

    标签: javascript jquery jquery-selectors traversal


    【解决方案1】:

    在 jQuery 中,您可以使用 nextUntil() 方法和 :not 选择器创建 nextWhile() 等效项。简单地说,while (condition is true) { do something }until (condition is false) { do something } 是一样的。

    考虑这个技巧示例,您需要选择第一个 .parent 后面的所有 .child 元素:

    <ul id="test">
      <li class="parent"></li>
      <li class="child"></li>
      <li class="child"></li>
      <li class="child"></li>
      <li class="divider"></li>
      <li class="parent"></li>
      <li class="child"></li>
      <li class="child"></li>
      <li class="child"></li>
    </ul>
    

    下面的代码大致相当于.nextWhile(".child"),并选择了.child这三个元素:

    $("#test .parent:first").nextUntil(":not(.child)");
    

    【讨论】:

      【解决方案2】:

      更新:放弃递归的想法,决定计数和切片(见最后一个例子)。

      初始尝试:
      此代码有问题 - 它只返回最后两项,因此不适用于 3 项以上。

      jQuery.fn.nextWhile = function(f)
      {
          if( this.next(f).html() )
          {
              return this.next(f).nextWhile(f).andSelf();
          }
          else
          {
              return this;
          }
      };
      


      当前版本:

      jQuery.fn.nextWhile = function(f)
      {
          var Next = this.next(f);
          var Pos = 0;
      
          while( Next.length > 0 )
          {
              Pos++;
              Next = Next.next(f);
          }
      
          return this.nextAll(f).slice(0,Pos);
      }
      

      这似乎工作正常,但我不确定选择所有内容然后只从中切出一小部分是否有任何性能损失?

      【讨论】:

      • 只检查 this.next(f).length > 0 怎么样?
      • 是的,这更有意义;我想踢自己。
      • 等等,这只是返回最后两个项目 - 所以如果 3 个或更多项目不起作用
      • 如果性能下降,请尝试调整选择器为您进行切片:this.nextAll(f + ':lt(' + Pos + ')')
      【解决方案3】:

      我的版本:

      $.fn.extend({
        nextWhile: function(selector) {
          var $result = $([]);
          this.each(function() {
            var $next = $(this).next();
            while ($next.is(selector)) {
              $result = $result.add($next);
              $next = $next.next();
            }
          });
          return $result;
        }
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-12
        • 1970-01-01
        • 2012-02-23
        • 1970-01-01
        相关资源
        最近更新 更多