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

IT技术 javascript css mootools css-selectors
2021-02-26 12:31:16

我有一个嵌套的可排序列表,可以动态添加或删除项目,并且可以嵌套 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++;
    });
}
2个回答
ul > li

只有直接的孩子。因此,例如,要仅执行您可以使用的顶级列表元素:

#parent > li

注意:这在 IE6 上不受支持。

向后兼容的常见解决方法是执行以下操作:

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

它更乏味,因为您必须应用样式然后将它们关闭(您可能不一定知道旧值是什么),但它是唯一对 IE6 友好的纯 CSS 解决方法。

编辑:好的,您有一个 MooTools 特定问题。getElements() 返回所有后代,而不仅仅是直接的孩子。尝试使用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++;
        });
    });
}

或类似的东西。

#parent > li 绝对只做直接的孩子。如果那不起作用,您还有其他事情要做。可能需要更多信息。
2021-05-01 12:31:16
谢谢您的帮助。我最终做了类似的事情。
2021-05-02 12:31:16
MooTools 允许我使用 CSS3 选择器,但因为我无法仅更改直接子项,它也错误地更改了我所有子列表的数字。
2021-05-03 12:31:16
无论出于何种原因,显然#parent > li不是有效的 CSS。Chrome 实际上抱怨它,所以我在规范上查找它,果然它只允许格式的通用元素名称(没有 id 选择)E > F
2021-05-09 12:31:16
谢谢,但 MooTools 处理 IE6 问题,所以这不是我想要的。我正在寻找一种方法来重置跨度的文本以指示该列表的正确位置,而不是父或子列表,这就是问题所在。
2021-05-19 12:31:16

原来的问题没有回答。:only-child 仅在独生子没有后代的情况下才有效。原始帖子表明包含后代子项是由于 ul>li 而实际上是由于 :only-child 中的错误。矛盾的是, :first-child 选择具有后代孩子的列表中的第一个孩子,就像 last-child 一样,但 :only-child 不会。我在 Firefox、Opera 和 Chrome 中检查了这个。下面是一个例子:

<!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>

要激活 :first-child 和 :last-child 规则,请取消对最后两项的注释。在实施选择器3级标准因此处于主流浏览器不一致。当存在 :only-child 规则并且唯一的孩子有后代时,不应激活 :first-child 规则。在这个例子中,独生子女应该是红色的,但它是绿色的。