伪类nth-of-type在特定类上不适用。

3
第一次我的HTML、CSS看起来完美,但如fiddle所示,当点击按钮时,我想隐藏/显示一些.show元素。当我隐藏它们时,CSS被破坏了。我不知道我漏掉了什么。

HTML:

<div>
    <span class="show">box</span>
    <span class="show">box</span>
    <span class="show">box</span>
    <span class="show">box</span>
    <span class="show">box</span>
    <span class="show">box</span>
    <span class="show">box</span>
    <span class="show">box</span>
</div>
<input type="button" id="button" value="click" />

CSS:

div .show:nth-of-type(-n+4) {
    margin-top:0;
}
div .show:nth-of-type(4n) {
    margin-right:0;
}

JS:

$("#button").click(function () {
    $("span:eq(0),span:eq(2)").toggle().toggleClass("show");
});

这里是Jsfiddle。

任何帮助都将不胜感激。

谢谢您的时间。


这是你的真实情况,还是一个简化的情况来展示问题?因为如果这是真实情况,那么你可以忘记nth-of-type样式,只需调整容器的上部和右部填充即可... - vals
@vals 不,这只是一个简化的情况。实际情况非常复杂。 - codingrose
@Hiral 你好,我遇到了同样的问题,但是无法通过以下答案解决,你能帮我解决我的问题吗? - Dhaval Panchal
@DhavalPanchal 你能展示一个样本吗? - codingrose
1个回答

6
:nth-of-type 不仅会计算 .show 元素,它将计算 所有spans。因此,当您隐藏其中的一些元素时,即使它们被隐藏,它们仍然会被计算在内。
如果您要显示和隐藏这些 spans,则 nth-of-type 可能不是您需要的东西。
我不是 CSS 专家。有两个选择:
1. 不要隐藏元素,detach 它们,稍后再重新附加它们。然后它们就不再是父元素的一部分了,:nth-of-type 将继续工作。请参见下面的示例。 2. (我不喜欢这个方法,但是……)不使用 :nth-of-type,而是使用您通过 JavaScript 分配的类来显示/隐藏 spans(基本上运行通过可见的那些并为它们分配类以执行所需操作)。
以下是执行 detach/reattach 操作的示例:Fiddle
// Get the spans
var $spans = $("#container span");

// Assign them indexes
$spans.each(function(index) {
    this.setAttribute("data-index", index);
});

// Attach/detach on a toggle
var detached;

$("#button").click(function () {
    if (detached) {
        reattach(detached);
        detached = undefined;
    }
    else {
        detached = detach();
    }
});

function detach() {
    var rnd1, rnd2;

    // Pick two at random
    rnd1 = Math.floor(Math.random() * $spans.length);
    do {
        rnd2 = Math.floor(Math.random() * $spans.length);
    }
    while (rnd2 === rnd1);

    // Detach them
    return $("#container span:eq(" + rnd1 + "),span:eq(" + rnd2 + ")").detach();
}

function reattach(spans) {
    spans.each(function() {
        var $span = $(this),
            index = +$span.attr("data-index");
        if (index === 0) {
            $span.prependTo("#container");
        }
        else {
            $span.insertAfter($spans[index - 1]);
        }
    });
}

请注意,包含
不能有空文本节点作为其第一个子元素(您的代码段有此问题,我已在我的代码中将其删除)。这是因为当我们把放回去时,由于我们总是按顺序进行操作,如果我们正在重新附加第一个,我们必须使用prependTo而不是insertAfter,而文本节点会破坏这种顺序。

那么,解决方案是什么? - codingrose
将它们存储在一个变量中并从DOM中删除? - enguerranws
为什么不使用:nth-of-type而是使用:nth呢? - Barmar
@Hiral:我添加了一个“detach”示例。只是简单的部分(分离)。稍微难一点的部分(重新连接,只是稍微难一点,因为你必须记住它们去哪里)和类的解决方案留给你。 :-) - T.J. Crowder
@Hiral:我开始想知道重新将它们放回正确的位置有多难,但实际上并不难。我已经更新了答案。 - T.J. Crowder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接