javascript 如何让第 n 个子选择器跳过隐藏的 div
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32355054/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get nth-child selector to skip hidden divs
提问by Deepak Yadav
I have a few random blocks. Whenever a block falls in the new row, I am making it look different. When the user clicks on a button, I hide few blocks by display:none
, and the problem occurs. The nth-child
selector also counts hidden elements.
我有几个随机块。每当一个块落入新行时,我都会让它看起来不同。当用户单击按钮时,我隐藏了几个块display:none
,然后出现了问题。该nth-child
选择也算隐藏要素。
Is there way to ignore those specific blocks, so that again every row has a different style? This is an example of a similar scenario.
有没有办法忽略那些特定的块,这样每一行都有不同的风格?这是类似场景的示例。
$('.hide-others').click(function () {
$('.css--all-photo').toggleClass('hidden');
})
.board-item--inner {
height:200px;
background:tomato;
text-align:center;
color:#fff;
font-size:33px;
margin-bottom:15px;
border:2px solid tomato;
}
@media (min-width:768px) and (max-width:991px) {
.board-item:nth-child(2n+1) .board-item--inner {
border:2px solid #000;
background:yellow;
color:#000;
}
}
@media (min-width:992px) and (max-width:1199px) {
.board-item:nth-child(3n+1) .board-item--inner {
border:2px solid #000;
background:yellow;
color:#000;
}
}
@media (min-width:1200px) {
.board-item:nth-child(4n+1) .board-item--inner {
border:2px solid #000;
background:yellow;
color:#000;
}
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="container">
<div class="form-group">
<button class="btn btn-info hide-others" type="button">Hide others</button>
</div>
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">1</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">2</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item css--all-photo">
<div class="board-item--inner">3</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">4</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">5</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item css--all-photo">
<div class="board-item--inner">6</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">7</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item css--all-photo">
<div class="board-item--inner">8</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">9</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">0</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">10</div>
</div>
</div>
<div>
Simply go through the snippet or EXTERNAL FIDDLE, and you'll get my question.
只需浏览代码段或EXTERNAL FIDDLE,您就会得到我的问题。
I am specifically looking for a pure CSS solution. Please provide a fiddle for your answers!And I cannot remove those blocks permanently, my user has the option to filter files on button click, that is why hidden and shown scenario.
我特别在寻找纯 CSS 解决方案。 请为您的答案提供小提琴!而且我无法永久删除这些块,我的用户可以选择在单击按钮时过滤文件,这就是隐藏和显示场景的原因。
采纳答案by Michael Benjamin
When the user clicks on a button, I hide few blocks by
display:none
, and the problem occurs. Thenth-child
selector also counts hidden elements.Is there way to ignore those specific blocks, so that again every row has different style?
当用户单击按钮时,我隐藏了几个块
display:none
,然后出现了问题。该nth-child
选择也算隐藏要素。有没有办法忽略那些特定的块,这样每一行都有不同的风格?
The problem is that the nth-child()
selector looks at all siblings under the same parent regardless of styling. It doesn't matter that you've applied display: none
because CSS doesn't remove the element from the DOM, and therefore it's still a sibling.
问题是nth-child()
选择器会查看同一父级下的所有兄弟姐妹,而不管样式如何。您是否已应用并不重要,display: none
因为 CSS 不会从 DOM 中删除该元素,因此它仍然是一个兄弟元素。
From the spec:
从规范:
6.6.5.2.
:nth-child()
pseudo-classThe
:nth-child(an+b)
pseudo-class notation represents an elementthat has an+b-1 siblings before it in the document tree, for any positive integer or zero value of n, and has a parent element. (emphasis mine)
的
:nth-child(an+b)
伪级符号表示元素,其具有+ B-1的兄弟姐妹之前它在文档树中,对于任意的正整数或正的零值,并具有父元素。(强调我的)
In order for the nth-child
rules you've declared to work after a user clicks to hide divs, you need to remove the hidden divs from the DOM, so they no longer exist as siblings.
为了使nth-child
您在用户单击以隐藏 div 后声明的规则起作用,您需要从 DOM 中删除隐藏的 div,使它们不再作为兄弟姐妹存在。
In your question you request a CSS-only solution. But in your comments you say that the HTML is open for changes. You also use a bit of jQuery to hide elements.
在您的问题中,您要求仅使用 CSS 的解决方案。但是在您的评论中,您说 HTML 可以更改。您还可以使用一些 jQuery 来隐藏元素。
With one small line of code added to your jQuery the problem can be solved:
只需将一小行代码添加到您的 jQuery 中,问题就可以解决:
$('.hidden').remove();
The .remove()
methodtakes elements (and its descendants) out of the DOM. In this case it removes all elements with a class hidden
.
该.remove()
方法从 DOM 中取出元素(及其后代)。在这种情况下,它会删除所有具有 class 的元素hidden
。
CORRECTION
更正
The problem with remove()
is that elements taken from the DOM with this method can't be restored, and this breaks the toggle function.
问题remove()
在于无法恢复使用此方法从 DOM 中获取的元素,这会破坏切换功能。
Fortunately, jQuery offers an alternative: detach()
.
幸运的是,jQuery 提供了一个替代方案:detach()
.
The
.detach()
method is the same as.remove()
, except that.detach()
keeps all jQuery data associated with the removed elements. This method is useful when removed elements are to be reinserted into the DOM at a later time.
该
.detach()
方法与 相同.remove()
,除了.detach()
保留与已删除元素关联的所有 jQuery 数据。当稍后将删除的元素重新插入 DOM 时,此方法很有用。
So if we replace the original code...
所以如果我们替换原来的代码...
$('.hide-others').click(function () {
$('.css--all-photo').toggleClass('hidden');
})
...with this code...
...使用此代码...
var divs;
$('.photos-board-item').each(function(i){
$(this).data('initial-index', i);
});
$('.hide-others').on('click', function () {
if(divs) {
$(divs).appendTo('.row').each(function(){
var oldIndex = $(this).data('initial-index');
$('.photos-board-item').eq(oldIndex).before(this);
});
divs = null;
} else {
divs = $('.css--all-photo').detach();
}
});
... the grid works as intended. (code credit: @JosephMarikle)
...网格按预期工作。(代码来源:@JosephMarikle)
Now, regardless of which divs or how many are hidden, they can be toggled on and off without disrupting the visual design because the nth-child
selector is counting only "visible" siblings. No changes to the CSS. No changes to the HTML.
现在,无论隐藏了哪些 div 或隐藏了多少个 div,都可以在不破坏视觉设计的情况下打开和关闭它们,因为nth-child
选择器只计算“可见”的兄弟姐妹。CSS 没有变化。对 HTML 没有任何更改。
回答by c-smile
I would do this with combination of :nth-of-type
selector and small modification of your toggle function.
我会结合:nth-of-type
选择器和对切换功能的小修改来做到这一点。
Basic idea is not to remove those .css--all-photo
elements from the DOM but wrap them into <hidden>
containers. And unwrap()
to restore full set. In this case :nth-of-type
will do exactly what you did with :nth-child
.
基本思想不是.css--all-photo
从 DOM 中删除这些元素,而是将它们包装到<hidden>
容器中。并unwrap()
恢复全套。在这种情况下,:nth-of-type
将完全按照您对:nth-child
.
var state = false;
$('.hide-others').click(function () {
if( !state ) {
$('.css--all-photo').wrap('<hidden>');
state = true;
} else {
$('hidden').unwrap();
state = false;
}
})
hidden { display:none; }
.board-item--inner {
height:200px;
background:tomato;
text-align:center;
color:#fff;
font-size:33px;
margin-bottom:15px;
border:2px solid tomato;
}
@media (min-width:768px) and (max-width:991px) {
div.board-item:nth-of-type(2n+1) .board-item--inner {
border:2px solid #000;
background:yellow;
color:#000;
}
}
@media (min-width:992px) and (max-width:1199px) {
div.board-item:nth-of-type(3n+1) .board-item--inner {
border:2px solid #000;
background:yellow;
color:#000;
}
}
@media (min-width:1200px) {
div.board-item:nth-of-type(4n+1) .board-item--inner {
border:2px solid #000;
background:yellow;
color:#000;
}
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="container">
<div class="form-group">
<button class="btn btn-info hide-others" type="button">Hide others</button>
</div>
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">1</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">2</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item css--all-photo">
<div class="board-item--inner">3</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">4</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">5</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item css--all-photo">
<div class="board-item--inner">6</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">7</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item css--all-photo">
<div class="board-item--inner">8</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">9</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">0</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 board-item photos-board-item">
<div class="board-item--inner">10</div>
</div>
</div>
<div>
回答by Ramtin Gh
What you are looking for is nth-of-class which unfortunately does not exist! When you toggle hidden class with JS, that is the only difference between hidden and shown children, So you need to tell css to count divs of certain class, (lets say "shown" ), but unfortunately, css nth-child selector doesn't pay much attention to classes of the child. You can read more here.
您正在寻找的是第 n 级,不幸的是不存在!当您使用 JS 切换隐藏类时,这是隐藏和显示子项之间的唯一区别,因此您需要告诉 css 计算某个类的 div,(比如“显示”),但不幸的是,css nth-child 选择器没有不要太注意孩子的课。您可以在此处阅读更多内容。
回答by Leo Javier
here an example of what I mean: https://jsfiddle.net/happy2deepak/g7gL5zfb/4/In this case it will ignore elements with class .css--all-photo
... but you may use what ever class you want to ignore
这里是我的意思的一个例子:https: //jsfiddle.net/happy2deepak/g7gL5zfb/4/在这种情况下,它将忽略具有类的元素.css--all-photo
......但你可以使用你想要忽略的任何类
$('.hide-others').click(function () {
$('.user-a').not('.css--all-photo').toggleClass('hidden');
})