【问题标题】:How to select consecutive elements that match a filter如何选择与过滤器匹配的连续元素
【发布时间】:2010-09-09 22:00:28
【问题描述】:

举个例子:

<img class="a" />
<img />
<img class="a" />
<img class="a" id="active" />
<img class="a" />
<img class="a" />
<img />
<img class="a" />

(我只是以img标签为例,我的代码中不是这样的)

使用 jQuery,你将如何选择与#active(在本例中为中间四个)相邻的类为“a”的 img 标签?

你可以通过循环遍历所有后面和前面的元素来相当容易地做到这一点,当过滤条件失败时停止,但我想知道 jQuery 是否可以原生?

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    这是我最后想到的。

    // here's our active element.
    var $active = $('#active');
    
    // here is the filter we'll be testing against.
    var filter = "img.a";
    
    // $all will be the final jQuery object with all the consecutively matched elements.
    // start it out by populating it with the current object.
    var $all = $active;
    
    for ($curr = $active.prev(filter); $curr.length > 0; $curr = $curr.prev(filter)) {
        $all = $all.add($curr);
    }
    for ($curr = $td.next(filter); $curr.length > 0; $curr = $curr.next(filter)) {
        $all = $all.add($curr);
    }
    

    对于后续问题,我可以看到如何通过将其制成一个接受两个参数的函数来轻松概括它:一个初始元素和一个过滤器字符串 - 谁能指出我正确的方向以找出如何扩展jQuery对象添加这样的功能?


    编辑:我后来发现 each() 函数在某些用途上会做得相当好。在我自己的情况下,它并没有那么干净,因为我想要所有这些元素的单个 jQuery 对象,但这里是您如何将每个对象用于不同目的(在此示例中隐藏连续的“.a”元素:)

    $('#active')
        .nextAll()
        .each(hideConsecutive)
        .end()
        .prevAll()
        .each(hideConsecutive)
    ;
    function hideConsecutive(index, element) {
        var $e = $(element);
        if (!$e.is(".a")) {
            return false;    // this stops the each function.
        } else {
            $e.hide('slow');
        }
    }
    

    --

    编辑:我现在把它放在一个插件中。有兴趣的可以看看http://plugins.jquery.com/project/Adjacent

    【讨论】:

      【解决方案2】:

      我相信循环是你最好的选择。但是你可以尝试,每次激活,然后前后移动,直到条件中断,如果集合足够大,速度会更快。

      【讨论】:

      • 请您提供一些代码sn-p。这会很有帮助,因为我不太明白你的意思。
      【解决方案3】:

      下面的代码将添加两个新函数,nextConsecutive() 和 prevConsecutive()。他们应该做你想做的。

      $.each(['prev', 'next'], function(unusedIndex, name) { $.fn[ name + '连续' ] = function(matchExpr) {

          var $all = 
              (name == 'prev')
                   ? $(this).prevAll()
                   : $(this).nextAll();
          if (!matchExpr)
              return $all;
      
          var $notMatch = $($all).not(matchExpr).filter(':first');
          if ($all.index($notMatch) != -1)
              return $allConsecutive = $all.slice(0, $all.index($notMatch));
      
          return $all;
      };
      

      });

      【讨论】:

        【解决方案4】:

        波浪号 (~) 是 siblings selector:

        $('#active ~ img.a').hide();
        

        【讨论】:

          【解决方案5】:

          @Prestaul

          $('#active ~ img.a')
          

          只会选择以下的兄弟姐妹,也会包括不连续的兄弟姐妹。文档:http://docs.jquery.com/Selectors/siblings#prevsiblings

          【讨论】:

            【解决方案6】:

            这是另一种方法,虽然兄弟选择器的答案很酷:

            var next = $('#active').next('.a');
            var prev = $('#active').prev('.a');
            

            编辑:我重新阅读了您的要求,但这并不是您想要的。您可以使用 nextAll 和 prevAll,但它们也不会在没有类名的 IMG 处停止。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2011-03-06
              • 2020-03-06
              • 1970-01-01
              • 2021-12-16
              • 2015-09-12
              • 2010-12-07
              • 2016-06-09
              相关资源
              最近更新 更多