jQuery下一个相邻兄弟元素的选择器。

3

我一直在努力解决这个问题,但似乎没有什么好的解决方法。

如果我有以下HTML:

<ul>
    <li class="parent"> headertext </li>
    <li> text </li>
    <li> text </li>
    <li> text </li>
    <li class="parent"> headertext </li>
    <li> text </li>
    <li> text </li>
</ul>

现在,我该如何只选择第一个父元素(或第二个父元素)后面的
  • 标签?基本上是选择一个class为“parent”的
  • 和其后面的兄弟元素,直到它达到另一个具有parent类的

  • 我可以重新构造嵌套列表,但我不想这样做。有什么建议吗?
  • 7个回答

    11

    实际上,你可以很容易地使用nextUntil()来完成这个功能。 不需要编写自己的“nextUntil”,因为它已经存在。

    示例:

    $(".a").nextUntil(".b");
    

    或者像文森特建议的那样 -

    $(".parent:first").nextUntil(".parent");
    

    这在 jQuery 1.4 版本之前是不存在的,而该版本发布时间略晚于提问时间。但是现在没问题了 :) - Contra

    6
    你的问题根源在于你将被分类为父元素的
  • 实际上并不是它们下面的
  • 的父元素,它们是兄弟元素。jQuery有许多与实际父元素一起使用的函数。我建议真正修复你的标记。这比使用jQuery拼凑更快、更清洁、更易于维护,而且语义上更正确。

  • 我同意这一点,虽然我已经发布了一个潜在的解决方案。如果 DOM 关系匹配实际关系,那会容易得多。 - tvanfosson
    是的,实际上,我发帖后意识到“parent”类名有点不对。称其为“header”可能更好。毕竟我可能仍需使用嵌套列表。 - Contra
    我认为从长远来看,这是更好的方法。我知道你现在不想重新做,但以后你可能会感谢自己。 - Mark Hurd
    1
    当我注意到选择我想要的元素很困难时,我应该在最开始就重新做它,因为重新做标记比折磨我的jQuery代码要少得多 :) 吸取教训。 - Contra

    2

    我认为没有其他方法可以做到这一点,除非使用each函数,因为任何其他选择器也会选择第二个父级及其后续兄弟。

    function getSibs( elem ) {
        var sibs = [];
        $(elem).nextAll().each( function() {
            if (!$(this).hasClass('parent')) {
                sibs.push(this);
            }
            else {
                return false;
            }
        });
        return $(sibs);
     }
    

    发抖 这是个好主意,但是天啊,我自己用起来会很讨厌的。 :) - Mark Hurd
    哈哈,其实,那非常接近我当前正在使用的解决办法 :) 羞愧 - Contra

    1

    你必须自己运行循环,因为jQuery不知道如何在特定条件下停止。

    jQuery.fn.nextUntil = function(selector)
    {
        var query = jQuery([]);
        while( true )
        {
            var next = this.next();
            if( next.length == 0 || next.is(selector) )
            {
                return query;
            }
            query.add(next);
        }
        return query;
    }
    
    // To retrieve all LIs avec a parent
    $(".parent:first").nextUntil(".parent");
    

    但是您可能更好地使用一个真正结构化的列表来处理父/子关系

    <ul>
    <li class="parent"> <span>headertext</span>
        <ul>
        <li> text </li>
        <li> text </li>
        <li> text </li>
        </ul>
    </li>
    <li class="parent"> <span>headertext</span>
        <ul>
        <li> text </li>
        <li> text </li>
        </ul>
    </li>
    </ul>
    

    嗯,我现在意识到这更干净了。正如有人提到的那样,更容易处理。我只是认为有一些选择器的魔法我无法理解,但看来如果不事后操纵数组就不可能做到。 - Contra

    0
    <html>
        <head>
            <script type="text/javascript">
                $(document).ready(function() {
                    $("a").click(function() {
                        var fred = $("li").not('.parent').text();
                        $('#result').text(fred);           
                    });
                });         
            </script>
        </head>
        <body>
            <a href="#">Click me</a>
            <ul>
                <li class="parent"> headertextA </li>
                <li> text1 </li>
                <li> text2 </li>
                <li> text3 </li>
                <li class="parent"> headertextB </li>
                <li> text4 </li>
                <li> text5 </li>
            </ul>
            <div id="result"></div>
        </body>
    </html>
    

    0

    0
    $("li.parent ~ li");
    

    $("li.parent ~ li:not(li.parent)"); <<<<< 这将排除下一个 class="parent"。但它并不止于此…… - Ropstah
    是的,我刚刚写了完全相同的代码,但正如你所提到的那样,它在达到下一个class=parent时并不停止。 - Contra

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接