Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
167 views
in Technique[技术] by (71.8m points)

javascript - CSS selector for targeting only immediate children and not other identical descendants

I have a nested sortable list that can have items dynamically added or removed and can be nested n-levels deep. On nesting, a new ul element is injected into whatever li element is selected to be the parent. The initial state of the list is something like the following:

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

I'm using MooTools to do the sort, etc., and it works fine, but I'm having trouble resetting the position text correctly on sort. Every CSS selector I try to use also includes all of the children rather than just the li elements that belong in the list and not any belonging to sublists. Assume that except for id, position, and text, each li element in all lists is identical to all others. Is there a selector for getting only the immediate children? Is there another way to do this?

I tried some child selectors like the ones mentioned:

  • ul > li Will select all li elements that are a child of a ul, not just the immediate children
  • #parent > li Does the same as above.

Here is the function that I'm currently having run when an item is dropped, which doesn't handle the sorting, which works fine, just updating the position. Note that it is also MooTools syntax:

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++;
        });
    });
}

Currently, changing any item order on the main level will renumber everything 1-12, even the sublists. Changing any item on a sublist will give the correct numbers for that list, but cause the parent lists to incorrectly count all child li elements in numbering.

I feel like this is an ugly hack, but it works:

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++;
    });
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...