jQuery - 关于“nextWhile”遍历的建议?

Posted

技术标签:

【中文标题】jQuery - 关于“nextWhile”遍历的建议?【英文标题】:jQuery - suggestions for a "nextWhile" traversion? 【发布时间】: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 的情况下实现。

【问题讨论】:

【参考方案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;
  
);

【讨论】:

以上是关于jQuery - 关于“nextWhile”遍历的建议?的主要内容,如果未能解决你的问题,请参考以下文章

关于jquery的$each((Object, function(p1, p2)用法

关于链表的常见算法

关于哈希表的常见算法

jquery中遍历指定的对象和数组是哪个方法

总结几个关于 jQuery 用法

关于jquery的each