CSS选择器仅用于定位直接子项而不是其他相同的后代

Vir*_*dia 62 javascript css mootools css-selectors

我有一个嵌套的可排序列表,可以动态添加或删除项目,并可以嵌套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>
Run Code Online (Sandbox Code Playgroud)

我正在使用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++;
        });
    });
}
Run Code Online (Sandbox Code Playgroud)

目前,更改主级别的任何项目顺序将重新编号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++;
    });
}
Run Code Online (Sandbox Code Playgroud)

cle*_*tus 95

ul > li
Run Code Online (Sandbox Code Playgroud)

只有直系孩子.因此,例如,要只使用您可以使用的顶级列表元素:

#parent > li
Run Code Online (Sandbox Code Playgroud)

注意: IE6不支持此功能.

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

#parent li { /* style appropriately */ }
#parent li li { /* back to normal */ }
Run Code Online (Sandbox Code Playgroud)

这更乏味,因为你必须应用样式然后关闭它们(你可能不一定知道旧的值是什么)但它是唯一的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++;
        });
    });
}
Run Code Online (Sandbox Code Playgroud)

或类似的东西.

  • 无论出于何种原因,显然`#parent> li`不是有效的CSS.Chrome实际上抱怨它,所以我查看了规范,确定它只允许格式为"E> F"的通用元素名称(无ID选择). (5认同)