jQuery - 关于“下一次”穿越的建议?

时间:2009-02-12 13:22:09

标签: javascript jquery jquery-selectors traversal

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的情况下实现。

3 个答案:

答案 0 :(得分:6)

在jQuery中,您可以使用nextUntil()方法和:not选择器创建等效nextWhile()。简而言之, while (condition is true) { do something } until (condition is false) { do something } 相同。

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

<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)");

答案 1 :(得分:1)

更新: 放弃递归的想法并决定计算和切片(参见上一个示例)。

初步尝试:
此代码有缺陷 - 它只返回最后两项,因此不适用于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);
}

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

答案 2 :(得分:0)

我的版本:

$.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;
  }
});