第一个孩子的造型只适用于第一个元素

时间:2017-09-20 10:52:22

标签: javascript css-selectors

我得到了一些代码,我可以通过第一个孩子选择一些元素,然后相应地设置样式。我注意到它表现得非常奇怪,并且css仅应用于第一个元素。我试着用JS选择它们,看起来,虽然我做的完全一样,只是在另一个元素上,但它并没有返回div。

代码:



console.log(document.querySelector(".index-0:first-child")); // returns div
console.log(document.querySelector(".index-1:first-child")); // returns null

.index-0:first-child {
  color: green;
}

.index-1:first-child {
  color: blue;
  /* doesn't work */
}

<div class="index-0">
  <p class="message"></p>
  <div class="shout">
    <span>Message 1</span>
  </div>
</div>
<div class="index-1">
  <p class="message"></p>
  <div class="shout">
    <span>Message 2</span>
  </div>
</div>
&#13;
&#13;
&#13;

jsfiddle:https://jsfiddle.net/a4k03eny/1/

1 个答案:

答案 0 :(得分:2)

您误解了CSS选择器的工作原理。 (你并不孤单;这是一个非常频繁的误解。).index-1:first-childdiv.foo等复合选择器是&#34; AND&#34;各个部分的操作:.index-1:first-child表示它匹配的是一个元素index-1 是其父级的第一个子元素。您的.index-1元素不是其父母中的第一个孩子,而是第二个孩子。

在这种情况下,您可以使用.index-1设置样式,而不使用:first-child位。

(如果您的目标是在 .index-1中为第一个孩子设置样式,请添加>(a child combinator):

.index-1 > :first-child {
    color: green;
}

...但我不认为你正在尝试做什么。或者您可以使用空格[descendant combinator],但这适用于.index-1中{strong>所有元素,这些元素是他们父母的第一个孩子,我也怀疑它不是&#39 ; t你想做什么。)

发表评论:

  

我想以不同方式设置具有新类的第一个元素。

您可以将.index-1:first-child:not(.index-1) + .index-1

合并来实现
.index-1:first-child, :not(.index-1) + .index-1 {
    color: blue;
}

后者使用相邻兄弟组合来说&#34;将规则应用于.index-1之后不立即的.index-1:< / p>

&#13;
&#13;
console.log(document.querySelector(".index-0:first-child, :not(.index-0) + .index-0"));
console.log(document.querySelector(".index-1:first-child, :not(.index-1) + .index-1"));
&#13;
.index-0:first-child, :not(.index-0) + .index-0 {
    color: green;
}

.index-1:first-child, :not(.index-1) + .index-1 {
    color: blue;
}
&#13;
<div class="index-0">
  <p class="message"></p>
  <div class="shout">
    <span>Message 1</span>
  </div>
</div>
<div class="index-1">
  <p class="message"></p>
  <div class="shout">
    <span>Message 2</span>
  </div>
</div>
&#13;
&#13;
&#13;

当然,这需要您专门设置样式(.index-0.index-1等规则)。您无法在CSS中执行一般,但您可以使用JavaScript。这将查看类index的所有元素,如果有index-N类名称,则选择它们,并在任何给定的运行中将highlight添加到第一个:

var lastClass = null;
document.querySelectorAll(".index").forEach(function(e) {
  var m = e.className.match(/(?:^| )(index-\d+)(?: |$)/);
  var thisClass = m ? m[1] : null;
  if (thisClass != lastClass) {
    lastClass = thisClass;
    e.classList.add("highlight");
  }
});

示例:

&#13;
&#13;
var lastClass = null;
document.querySelectorAll(".index").forEach(function(e) {
  var m = e.className.match(/(?:^| )(index-\d+)(?: |$)/);
  var thisClass = m ? m[1] : null;
  if (thisClass != lastClass) {
    lastClass = thisClass;
    e.classList.add("highlight");
  }
});
&#13;
.highlight {
    color: green;
}
&#13;
<div class="index index-0">
  <p class="message"></p>
  <div class="shout">
    <span>first .index-0</span>
  </div>
</div>
<div class="index index-0">
  <p class="message"></p>
  <div class="shout">
    <span>second .index-0 in a row</span>
  </div>
</div>
<div class="index index-1">
  <p class="message"></p>
  <div class="shout">
    <span>first .index-1</span>
  </div>
</div>
&#13;
&#13;
&#13;

注意:许多浏览器现在支持forEach返回的NodeList上的querySelectorAll,但不是全部。如果遗漏,你可以填充它:

if (typeof NodeList !== "undefined" &&
    NodeList.prototype &&
    !NodeList.prototype.forEach) {
    Object.defineProperty(NodeList.prototype, "forEach", {
        value: Array.prototype.forEach
    });
}