如何选择与过滤器匹配的连续元素

Posted

技术标签:

【中文标题】如何选择与过滤器匹配的连续元素【英文标题】: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 是否可以原生?

【问题讨论】:

【参考方案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 处停止。

【讨论】:

以上是关于如何选择与过滤器匹配的连续元素的主要内容,如果未能解决你的问题,请参考以下文章

如何使用正则表达式过滤元素[重复]

[ jquery 过滤器 parentsUntil([expr|element][,filter]) ] 此方法用于在选择器的基础之上搜索查找当前元素的所有的父辈元素,直到遇到与表达式和限定条件相匹配

jQuery学习笔记使用选择器二

[ jquery 过滤器 find(expr|obj|ele) ] 此方法用于在选择器的基础之上搜索所有与指定表达式匹配的元素,这个函数是找出正在处理的元素的后代元素的好方法

如何实现子查询以选择与三个主题中的两个主题匹配的行?

如何选择具有类的所有元素,除了具有与模式匹配的id的祖先的元素?