为啥 nth-child(1) 适用于所有孩子?

Posted

技术标签:

【中文标题】为啥 nth-child(1) 适用于所有孩子?【英文标题】:why is nth-child(1) applying to all children?为什么 nth-child(1) 适用于所有孩子? 【发布时间】:2013-11-28 01:09:54 【问题描述】:

基于这个非常基本的 html 结构:

<div>This is a cube</div>
<div>This is a triangle</div>
<div>This is a big, green circle</div>

我已经设置了以下 jQuery:

$(document).ready(function () 

    $("div:nth-child(1)").addClass("cube-text text");
    $("div:nth-child(2)").addClass("triangle-text text");
    $("div:nth-child(3)").addClass("circle-text text");

    $("div:nth-child(1)").wrap("<div class='cube shape'></div>");
    $("div:nth-child(2)").wrap("<div class='triangle shape'></div>");
    $("div:nth-child(3)").wrap("<div class='circle shape'></div>");

    $(".shape").wrap( "<div class='inner'></div>" );
    $(".inner").wrap( "<div class='outer'></div>" );
    $(".outer").wrap( "<div class='column'></div>" );

    $(".outer:nth-child(1)").addClass("cube-anim");
    $(".outer:nth-child(2)").addClass("triangle-anim");
    $(".outer:nth-child(3)").addClass("circle-anim");
);

由于某种原因,最后三行似乎没有按预期工作。他们应该将相应的类添加到在前几行中创建的“.outer”div 的连续实例中。我尝试过使用这种特定语法的各种替代方法,例如...

div .outer:nth-child

.column .outer:nth-child

.column:nth-child

还有其他几个人,通过反复试验,试图获得想要的结果。

我试图让每个“.outer”容器 div 拥有一个额外的类,CSS3 将调用该类来呈现一些基于 @keyframe 的动画。

这里是 jsfiddle:http://jsfiddle.net/5NEPu/

【问题讨论】:

为什么不根据元素中的文本添加类和包装器? 在这里回答了类似的问题 - ***.com/questions/19909458/… 因为这是我的任务,adeno 看起来很简单 -> jsfiddle.net/5NEPu/3 这样看...当你将它应用到外部时,每个外部 div 都是其父级的第一个子级,因此当你选择所有作为其父级的第一个子级的外部 div 时,你全部选中。另外两个什么都不做,因为每列只有一个外部 div。 jsfiddle.net/nM2z4 【参考方案1】:

每个.outer 都是.column 的唯一子代,因此:nth-child(1)(在功能上是equivalent to :first-child)将匹配所有它们,而nth-child(2)(3) 将永远不会匹配。

您需要使用:eq():

// selects first .outer in the DOM, as :eq is 0-based
$(".outer:eq(0)").addClass("cube-anim");

:nth-child() 与兄弟姐妹在上层:

// selects .outer descendant of a column that is a first child.
// NOTE:
// Only works properly if the columns are the only children of the same parent
$(".column:nth-child(1) .outer").addClass("cube-anim"); 

我的意思是“仅适用”,如果列的父级的第一个子级不是列,则所有列的子级索引将偏移 1。如您所见,nth-child 相当脆弱在许多用例中。

使用.closest()的另一种可能的解决方案:

$('.triangle').closest('.outer').addClass("triangle-anim");

【讨论】:

我明白了。我的(不正确的)理解是 nth-child(n) 将应用于文档树中该元素的第 n 次出现。我现在明白了,因为每个 .outer 都是其父级的第一个(也是唯一一个)子级,所以使用我的原始语法并没有达到预期的结果 @BrianS 我还添加了一些关于nth-child 的额外注释,但您现在已经理解了。 =] 事情是,如果您单独包装每个元素并且您也不能将元素添加到同一个容器中,那么 nth-child 将会中断。所以,是的,在使用 nth-child 时要格外小心,并在您的 DOM 结构将来可能发生变化时避免使用它。【参考方案2】:

这是你的问题

$(".outer").wrap( "<div class='column'></div>" );

这会将.column 类应用于所有内容,这使得每个.outer 成为每列的第一个元素。你的选择器应该是:

$(".column:nth-child(1) .outer").addClass("cube-anim");
$(".column:nth-child(2) .outer").addClass("triangle-anim");
$(".column:nth-child(3) .outer").addClass("circle-anim");

【讨论】:

以上是关于为啥 nth-child(1) 适用于所有孩子?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 :nth-child() 来选择所有孩子中的所有其他 <div> ?

第n个孩子的问题-它确实计算了所有div,而不是某些类别的div [重复]

nth-child选择器二乘二除外

隐藏特定表的第n个孩子

nth-child() 选择器仅适用于选择的几个元素[重复]

使用 nth-child 作为 CSS 变量