【问题标题】:Sibling selectors and first-of-type don't work when I try to select the first ul element after a prior one当我尝试在前一个元素之后选择第一个 ul 元素时,兄弟选择器和第一个类型不起作用
【发布时间】:2021-11-08 19:54:57
【问题描述】:

对于上下文:我正在查看这个webpage,我正在尝试找出在开发控制台中放置什么来按星级对每个无序列表进行排序。这是我要重新排序的实际 html 的 sn-p:

<h3 id="invocations-level-1">Level 1</h3>
<p>some intro</p>
<ul>
  <!-- <li><a href="" class="rating-"></a><sup><a href="/dnd5/abbreviations/"></a></sup>: </li> -->
  <li><a href="https://www.dndbeyond.com/sources/phb/classes#AgonizingBlast" class="rating-blue">Agonizing Blast</a><sup><a href="/dnd5/abbreviations/">PHB</a></sup>: Nearly every Warlock takes this. The damage is simply too good to pass up. The damage grows
    multiplicatively as you get additional rays, so the total additional damage will range from +3 at low levels to a maximum +20 at 17th level.</li>
  <li><a href="https://www.dndbeyond.com/sources/phb/classes#ArmorofShadows" class="rating-orange">Armor of Shadows</a><sup><a href="/dnd5/abbreviations/">PHB</a></sup>: You already get light armor, and Mage Armor is only +1 AC over studded leather. You don't
    get enough invocations to justify wasting one on this. Hexblades might consider this to close the AC gap between light/medium and heavy armor, but I'm not convinced that this is better than multiclassing to get heavy armor proficiency.</li>
  <li><a href="https://www.dndbeyond.com/sources/phb/classes#BeastSpeech" class="rating-red">Beast Speech</a><sup><a href="/dnd5/abbreviations/">PHB</a></sup>: Very situational.</li>
</ul>
<h3 id="invocations-level-3">Level 3 (Requires Pact Boon)</h3>
<p>some intro</p>
<span id="some-ad"></span>
<span class="some-other-ad">...</span>
<ul><li>...</li></ul>

每个级别(1、3、5、7、9、12、15)的每个列表当前按调用名称的字母顺序排序(例如 Agonizing Blast、Armor of Shadows ),但我希望重新- 根据类别(rating-{blue,green,orange,red} 形式)对其进行排序。

我的 MVCE 代码仅适用于第一批 ul 元素:

[1, 3, 5, 7, 9, 12, 15].forEach((level, index) => $$('div#main-content > ul')[index].innerHTML = [].map.call(['blue', 'green', 'orange', 'red'].flatMap(colour => $$('#invocations-level-'+level+' + p + ul li a.rating-' + colour)), function(el) {
    return el.parentElement.outerHTML;
}));

(这里使用的是原生document.querySelectorAll,不涉及jQuery atm)

这仅适用于第一个 ul 元素,因为这部分 $$('#invocations-level-1 + p + ul li a.rating-blue') 在直接同级选择方面过于具体。在第二部分,&lt;h3 id="invocations-level-3"&gt;Level 3 (Requires Pact Boon)&lt;/h3&gt; 之后有一个段落,但也有一些跨度。在后面的部分(上面未列出)中,没有跨度或段落元素。

我已经尝试了几次兄弟选择器组合的迭代,例如 $$('#invocations-level-3 ~ ul:first-of-type')(这在 -level-3 上不起作用,尽管在 -level-1 工作),还有 $$('#invocations-level-3 ~ ul:not(ul~ul)') 再次在 -level-1 上工作,但随后没有。

我可以像 $$('#invocations-level-3 ~ ul')[0] 这样使用索引访问,但是我无法继续深入到选择器的 ' ... li a.rating-'+colour' 部分。

我可以在不涉及 jQuery 且只使用一个选择器的情况下做到这一点吗?

【问题讨论】:

    标签: javascript html css css-selectors


    【解决方案1】:

    您可以完全使用 CSS 来做到这一点。但是,该类必须直接应用于&lt;li&gt; 标签。然后在 &lt;ul&gt; 上使用 flexbox 并将 order-porperty 应用到一个类。

    ul { 
      display: flex;
      flex-direction: column;
    }
    
    .rating-red {
      order: 1;
    }
    
    .rating-orange {
      order: 2;
    }
    
    .rating-blue {
      order: 3;
    }
      
    <ul>
      <!-- <li><a href="" class="rating-"></a><sup><a href="/dnd5/abbreviations/"></a></sup>: </li> -->
      <li class="rating-blue"><a href="https://www.dndbeyond.com/sources/phb/classes#AgonizingBlast">Agonizing Blast</a><sup><a href="/dnd5/abbreviations/">PHB</a></sup>: Nearly every Warlock takes this. The damage is simply too good to pass up. The damage grows
        multiplicatively as you get additional rays, so the total additional damage will range from +3 at low levels to a maximum +20 at 17th level.</li>
      <li class="rating-orange"><a href="https://www.dndbeyond.com/sources/phb/classes#ArmorofShadows">Armor of Shadows</a><sup><a href="/dnd5/abbreviations/">PHB</a></sup>: You already get light armor, and Mage Armor is only +1 AC over studded leather. You don't
        get enough invocations to justify wasting one on this. Hexblades might consider this to close the AC gap between light/medium and heavy armor, but I'm not convinced that this is better than multiclassing to get heavy armor proficiency.</li>
      <li class="rating-red"><a href="https://www.dndbeyond.com/sources/phb/classes#BeastSpeech">Beast Speech</a><sup><a href="/dnd5/abbreviations/">PHB</a></sup>: Very situational.</li>
    </ul>

    【讨论】:

    • 我不是网站的所有者,所以无法更改 html。
    • 这对于如果/当我接下来需要它时绝对有用
    • 您可以使用 JS 将一个类添加到带有 classList.add('class-name') 的列表项中,因此您只需检查列表内部 HTML 的 aprt 是否有 class 关键字,然后将该类应用于 @ 987654327@据此。如果有人解决了这个问题,我可以稍后再检查。否则我会为我有更多时间编写脚本。
    • 我想通了,看我的回答
    【解决方案2】:

    使用 nth-of-type 随每个 ul 工作而扩展

    [1, 3, 5, 7, 9, 12, 15].forEach((level, index) => $$('div#main-content > ul')[index].innerHTML = [].map.call(['blue', 'green', 'orange', 'red'].flatMap(colour => $$('#invocations-level-'+level+' ~ ul:nth-of-type('+(index+1)+') li a.rating-' + colour)), function(el) {
        return el.parentElement.outerHTML;
    }));
    

    看起来ul:nth-of-type('+(index+1) 是必需的,因为它永远不是#invocations-level-* 的兄弟姐妹,而是所选父母的孩子。当您记住a CSS rule is read right-to-left 时,这是有道理的,因此必须在nth-of-type 之后评估~

    【讨论】:

    • 从右到左求值是一个实现细节,旨在从主题本身开始提高性能 - 这不是原因,也不会影响选择器如何理解。但巧合的是,我们忽略了 ~ 的左侧并单独考虑了 ul:nth-of-type(index+1) ,它恰好在右侧。正如您所说, :nth-of-type() 不会相对于兄弟选择器的左侧进行评估 - 相反,它相对于元素父级的所有子级(尽管,与整个文档无关,但我明白你的意思)。
    • @BoltClock 是巧合吗?对我来说,让nth-of-type 以它的方式工作的决定听起来很合乎逻辑,因为我们必须首先选择 all ul 元素,并且在这样做之前不能按兄弟姐妹缩小范围.我猜这只是语义上的巧合……
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多