匹配整个文档中某种类型的第一个/第n个元素

时间:2014-12-17 11:19:00

标签: html css css-selectors

如何指定整个文档的:first-of-type

我想设置HTML的第一个<p>样式,而不是它所在的位置(我不想写section p:first-of-type因为它可能位于不同HTML文档的其他位置)。

p {
  background:red;	
}

p:first-of-type {
  background:pink;
}

p:last-of-type {
  background:yellow;	
}
<body>
  <section>
    <p>111</p>
    <p>222</p>
    <p>333</p>
  </section>
  <p>444</p>
  <p>555</p>
</body>

1 个答案:

答案 0 :(得分:8)

单凭CSS,遗憾的是这是不可能的。 :first-of-type伪类states的文档:

  

:first-of-type伪类表示一个元素,它是其父元素子元素列表中第一个兄弟元素。

这意味着:first-of-type相对于其父类而不是文档的根(或body元素)应用于其类型的第一个元素。在这种情况下。


JavaScript解决方案

:first-of-type

我们可以通过引入一些JavaScript来实现这一点。我们需要的只是JavaScript的querySelector()方法,它从指定的选择器中提取第一个匹配元素。

在这个例子中,我将你的:first-of-type伪类更改为“类型优先”类,然后使用JavaScript将此类添加到使用{{1}时返回的元素}:

querySelector('p')
document.querySelector('p').className += ' first-of-type';
p {
  background:red;	
}


p.first-of-type {
  background: pink;
}

<body> <section> <p>111</p> <p>222</p> <p>333</p> </section> <p>444</p> <p>555</p> </body>:nth-child

对于:last-of-type:nth-child,我们可以使用JavaScript为我们提供的类似方法::last-of-type。此方法将所有匹配元素拉入NodeList(类似于数组),然后我们可以通过索引迭代或从内部选择特定元素:

querySelectorAll()
var elems = document.querySelectorAll('p');

// nth-of-type = NodeList[n - 1]
// e.g. to select the 3rd p element ("333"):
if (elems.length >= 2)
   elems[2].className += ' nth-of-type';

// last-of-type = NodeList length - 1
if (elems.length)
   elems[elems.length - 1].className += ' last-of-type';
p {
  background:red;	
}


p.nth-of-type {
  background: pink;
}

p.last-of-type {
  background: yellow;
}

请注意,我在两个选择器周围都包含<body> <section> <p>111</p> <p>222</p> <p>333</p> </section> <p>444</p> <p>555</p> </body>语句,以确保elems NodeList具有足够的元素,否则将引发错误。