CSS-селектор для таргетинга только на непосредственных потомков, а не на других идентичных потомков - PullRequest
59 голосов
/ 09 апреля 2009

У меня есть вложенный сортируемый список, в который можно динамически добавлять или удалять элементы, а также иметь 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 Выберет все li элементы, которые являются дочерними элементами ul, а не только непосредственными дочерними элементами
  • #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 ]

92 голосов
/ 09 апреля 2009
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++;
        });
    });
}

или что-то в этом роде.

0 голосов
/ 06 марта 2018

На оригинальный вопрос не было ответа. : only-child работает, только если у 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 уровня селекторов несовместима в основных браузерах. Правило: first-child не следует активировать, когда существует правило: only-child, а у уникального потомка есть потомки. В этом примере единственный ребенок должен быть красным, но зеленым.

...