CSS 选择器,只针对直系子女,而不是其他相同的后代

我有一个嵌套的可排序列表,可以动态添加或删除项目,并可以嵌套 n 级深。在嵌套时,一个新的 ul 元素被注入到选择作为父元素的 li 元素中。列表的初始状态如下:

<ul id="parent">
<li id="One"><a href="" class="listLink"><span class="position">1</span>One</a></li>
<li id="Two"><a href="" class="listLink"><span class="position">2</span>Two</a></li>
<li id="Three"><a href="" class="listLink"><span class="position">3</span>Three</a>
<ul>
<li id="A"><a href="" class="listLink"><span class="position">1</span>A</a></li>
<li id="B"><a href="" class="listLink"><span class="position">2</span>B</a></li>
<li id="C"><a href="" class="listLink"><span class="position">3</span>C</a></li>
<li id="D"><a href="" class="listLink"><span class="position">4</span>D</a></li>
<li id="E"><a href="" class="listLink"><span class="position">5</span>E</a></li>
<li id="F"><a href="" class="listLink"><span class="position">6</span>F</a></li>
</ul>
</li>
<li id="Four"><a href="" class="listLink"><span class="position">4</span>Four</a></li>
<li id="Five"><a href="" class="listLink"><span class="position">5</span>Five</a></li>
<li id="Six"><a href="" class="listLink"><span class="position">6</span>Six</a></li>
</ul>

我正在使用 MooTools 进行排序,等等,它工作得很好,但是我在排序时无法正确地重置位置文本。我尝试使用的每个 CSS 选择器也包含子元素的 所有,而不仅仅是属于列表的 li 元素,而不是属于子列表的任何元素。假设除了 id、 position 和 text 之外,所有列表中的每个 li 元素都与其他所有元素相同。是否有一个选择器只获得直接的孩子?还有别的办法吗?

我尝试了一些儿童选择器,就像上面提到的那些:

  • ul > li将选择作为 ul 的子元素的 所有 li 元素,而不仅仅是直接子元素
  • #parent > li和上面一样。

下面是当一个项被删除时我正在运行的函数,它不处理排序,它工作得很好,只是更新位置。请注意,它也是 MooTools 语法:

var drop = function(el){
el.getParents('ul').reverse().each(function(item){
var posCount = 1;
item.getElements('li a span[class=position]').each(function(pos){
pos.set('text', posCount);
posCount++;
});
});
}

目前,改变任何项目的顺序在主要水平将重新编号的一切1-12,甚至子清单。更改子列表上的任何项目都将为该列表提供正确的编号,但会导致父列表错误地计算编号中的所有子 Li 元素。

我觉得这是一个丑陋的黑客,但它的工作:

var drop = function(){
var ulCount = 1;
$$('ul').each(function(item){
if(item.get('id') != 'parent') {
item.set('id', 'id-'+ulCount);
}
var elId = item.get('id');
var posCount = 1;
$(document).getElements('#'+elId+'>li>a>span[class=position]').each(function(pos){
pos.set('text', posCount);
posCount++;
});
ulCount++;
});
}
77480 次浏览
ul > li

only does the immediate children. So, for example, to do only the top level list elements you could use:

#parent > li

Note: this isn't supported on IE6.

The common workaround for backwards compatibility is to do something like this:

#parent li { /* style appropriately */ }
#parent li li { /* back to normal */ }

It's more tedious because you have to apply styles and then turn them off (and you may not necessarily know what the old values are) but it's the only IE6-friendly pure CSS workaround there is.

Edit: Ok you have a MooTools specific issue. getElements() returns all descendants, not just immediate children. Try using getChildren().

var drop = function(el){
el.getParents('ul').reverse().each(function(item){
var posCount = 1;
item.getChildren("li").getElements("a span[class=position]").each(function(pos){
pos.set('text', posCount);
posCount++;
});
});
}

or something like that.

The original question was not answered. :only-child only works if the only-child has no descendant children. The original post suggested that the inclusion of descendant children was due to ul>li whereas it is in fact due to a bug in :only-child. Paradoxically :first-child selects the first child in a list with descendant children, as does last-child, but :only-child does not. I checked this in Firefox, Opera and Chrome. Here is an example:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8">
<style>
.list>ul>li:only-child {color:red}
.list>ul>li:first-child {color:green}
.list>ul>li:last-child {color:blue}
</style>
</head>
<body>
<div class="list">
<ul><li>Item one</li><ul>
<l>Subitem one</li>
<li>Subitem two</li></ul></li><!--<li>Item two</li>
<li>Item three</li>-->
</ul></div>
</body></html>

To activate :first-child and :last-child rules uncomment the last two items. The implementation of the Selectors Level 3 standard is thus inconsistent in major browsers. The :first-child rule should not be activated when there is an :only-child rule and a unique child has descendants. In the example the only-child should be red but it is green.