【问题标题】:Return list items based on class and position根据类和位置返回列表项
【发布时间】:2020-05-04 19:46:48
【问题描述】:

我正在使用作为分层菜单一部分的无序列表。我需要根据它们的类和列表位置返回列表项,以便我可以进行一些程序化 css 调整。这是一些示例 HTML:

<ul class="category1">    
    <li class="sec secactive" secid="360007912231" categoryid="360002246652" parentsecid="null" style="display: list-item;"><a href="myURL">Section1</a></li>    
    <li class="sec subsec" secid="360008584672" categoryid="360002246652" parentsecid="360007912231" style="background-color: red; display: list-item;"><a href="myURL">Subsection A</a></li>   
    <li class="sec subsec" secid="360008585372" categoryid="360002246652" parentsecid="360007912231" style="background-color: red; display: list-item;"><a href="myURL">Subsection B</a></li>    
    <li class="sec" secid="360007910471" categoryid="360002246652" parentsecid="null" style="display: list-item;"><a href="myURL">Section 2</a></li>    
    <li class="sec" secid="360007155641" categoryid="360002246652" parentsecid="null" style="display: list-item;"><a href="myURL">Section 3</a></li>
    <li class="sec subsec" secid="360008585592" categoryid="360002246652" parentsecid="360007912231" style="background-color: red; display: list-item;"><a href="myURL">Subsection A</a></li>
    <li class="sec" secid="360007106191" categoryid="360002246652" parentsecid="null" style="display: list-item;"><a href="myURL">Section 3</a></li>   
</ul>

如果您查看示例 HTML,您会看到每个列表项 (li) 都有一个“sec”类。在大多数情况下,列表项也会有其他类分配——例如“subsec”。

我正在尝试组合一些 jQuery,它允许我以编程方式定位任何紧接在没有“subsec”类分配的列表项之前的“subsec”列表项。因此,如果我们再次查看示例 HTML,我希望能够返回第 3 和第 6 个列表项。 (它们都有一个 'subsec' 类,并且它们出现在另一个没有 'subsec' 类的 li 之前。)

这是我尝试过的 jQuery,但它不能正常工作。 (它似乎针对的是所有“子秒”列表项,而不仅仅是我需要返回的那些。)

$("li.subsec").each(function() {
    if ($(this).next('li.sec') !='li.subsec');
    $(this).css("background-color", "red");
});

任何关于如何修复我的 jQuery 代码的建议将不胜感激。

【问题讨论】:

    标签: jquery list if-statement


    【解决方案1】:

    首先请注意,您应该使用外部 CSS 文件来存储样式规则,而不是内联 style 属性。此外li 元素默认为display: list-item,因此您无需显式设置它。

    关于该问题,您需要将.subsec 选择器提供给next() 并检查生成的jQuery 对象的length 以确定是否找到匹配项:

    $(".subsec").each(function() {
      if ($(this).next('li.subsec').length == 0)
        $(this).css("background-color", "red");
    });
    

    但是,使用filter() 可以更简洁:

    $(".subsec").filter((i, el) =&gt; $(el).next('li.subsec').length === 0).addClass('foo');
    .foo { background-color: #C00; }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <ul class="category1">
      <li class="sec secactive" secid="360007912231" categoryid="360002246652" parentsecid="null">
        <a href="myURL">Section1</a>
      </li>
      <li class="sec subsec" secid="360008584672" categoryid="360002246652" parentsecid="360007912231">
        <a href="myURL">Subsection A</a>
      </li>
      <li class="sec subsec" secid="360008585372" categoryid="360002246652" parentsecid="360007912231">
        <a href="myURL">Subsection B</a>
      </li>
      <li class="sec" secid="360007910471" categoryid="360002246652" parentsecid="null">
        <a href="myURL">Section 2</a>
      </li>
      <li class="sec" secid="360007155641" categoryid="360002246652" parentsecid="null">
        <a href="myURL">Section 3</a>
      </li>
      <li class="sec subsec" secid="360008585592" categoryid="360002246652" parentsecid="360007912231">
        <a href="myURL">Subsection A</a>
      </li>
      <li class="sec" secid="360007106191" categoryid="360002246652" parentsecid="null">
        <a href="myURL">Section 3</a>
      </li>
    </ul>

    顺便说一句,请小心为您的元素添加非标准属性,例如secidcategoryidparentsecid。它们可能会导致 UI 和 JS 出现问题。如果您想在 HTML 中存储元数据,我建议使用 data 属性。

    【讨论】:

    • 谢谢。您的代码建议确实有效。不幸的是(而且奇怪的是)直到我已经找到了另一个解决方案,我才看到它。
    【解决方案2】:

    您需要检查class 属性(函数prop())是否包含"subsec" 子字符串。

    $("li.subsec").each(function() {
        if ( !($(this).next().prop("class").includes("subsec") ) )
            $(this).css("background-color", "red");
        else
            $(this).css("background-color", "green");
    });
    

    在本例中,我为与条件不匹配的元素分配了不同的颜色(绿色)(为了覆盖 html 部分中的样式属性,无论如何它都会分配红色背景颜色)。

    下图显示了结果:

    或者,您可以通过为next() 元素发出hasClass() 方法(返回布尔值)来检查类的存在。这样支票就变成了

    $("li.subsec").each(function() {
        if ( !($(this).next().hasClass("subsec") ) )
            $(this).css("background-color", "red");
        else
            $(this).css("background-color", "green");
    });
    

    【讨论】:

    • 非常感谢您的回复。我尝试了您的代码,但它对我来说无法正常工作。我检查了控制台,我收到以下错误:“未捕获的 TypeError:无法读取 HTMLLIElement 处未定义的属性 'includes'。
    • @Marconi 您的列表与示例中显示的相同吗?
    • @Marconi 在我的 WAMP 环境中,使用 Firefox,当 subsec 位于列表末尾时,它也可以工作。
    • 我正在构建的实际菜单涉及多个 UL,但结构和类名与您在我最初的问题中看到的一样。我已经实现了一堆成功操作列表的代码块/函数,所以我不确定你提供的代码为什么会抛出错误。
    • @Marconi 可能是浏览器由于某种原因不支持 prop()
    【解决方案3】:

    以下代码对我有用:

    $("li.subsec").each(function() {
     if (!($(this).next().hasClass("subsec")))
     $(this).css("background-color", "red");
     });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-12-17
      • 2023-03-06
      • 2010-09-07
      • 1970-01-01
      • 2013-07-26
      • 2017-11-22
      • 2014-10-12
      相关资源
      最近更新 更多