Selector CSS para apuntar solo a los hijos inmediatos y no a otros descendientes idénticos


Tengo una lista clasificable anidada que puede tener elementos añadidos o eliminados dinámicamente y pueden anidarse n niveles de profundidad. Al anidar, se inyecta un nuevo elemento ul en cualquier elemento li seleccionado para ser el padre. El estado inicial de la lista es algo así como lo siguiente:

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

Estoy usando MooTools para hacer la ordenación, etc., y funciona bien, pero estoy teniendo problemas para restablecer el texto de posición correctamente en ordenar. Cada selector CSS que intento usar también incluye todo de la hijos en lugar de solo los elementos li que pertenecen a la lista y no cualquier pertenencia a sublistas. Supongamos que, a excepción de id, position y text, cada elemento li en todas las listas es idéntico a todos los demás. ¿Hay un selector para obtener solo los niños inmediatos? Hay otra manera de hacer esto?

Probé algunos selectores infantiles como los mencionados:

  • ul > li Seleccionará todos los elementos li que son un hijo de un ul, no solo el inmediato niños
  • #parent > li Hace lo mismo que el anterior.

Aquí está la función que actualmente estoy ejecutando cuando se suelta un elemento, que no maneja la ordenación, que funciona bien, solo actualizando la posición. Tenga en cuenta que también es la sintaxis de 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++;
        });
    });
}

Actualmente, cambiar el orden de cualquier elemento en el nivel principal renumerará todo del 1 al 12, incluso las sublistas. Cambiar cualquier elemento en una sublista dará los números correctos para esa lista, pero hará que las listas principales contar incorrectamente todos los elementos li secundarios en numeración.

Siento que esto es un truco feo, pero funciona:

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++;
    });
}
Author: the Tin Man, 2009-04-09

2 answers

ul > li

Solo lo hacen los hijos inmediatos. Así, por ejemplo, para hacer solo los elementos de la lista de nivel superior se puede utilizar:

#parent > li

Nota: esto no es compatible con IE6.

La solución común para la compatibilidad con versiones anteriores es hacer algo como esto:

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

Es más tedioso porque tienes que aplicar estilos y luego desactivarlos (y puede que no sepas necesariamente cuáles son los valores antiguos), pero es la única solución CSS pura compatible con IE6 ser.

Edit: Ok tiene un problema específico de MooTools. getElements () devuelve todos los descendientes, no solo los hijos inmediatos. Intenta usar 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++;
        });
    });
}

O algo así.

 85
Author: cletus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-06 12:55:36

La pregunta original no fue contestada. : only-child solo funciona si el only-child no tiene hijos descendientes. El post original sugirió que la inclusión de hijos descendientes se debió a ul > li, mientras que de hecho se debe a un error en :only-child. Paradójicamente: first-child selecciona el primer hijo en una lista con hijos descendientes, al igual que last-child, pero :only-child no lo hace. Revisé esto en Firefox, Opera y Chrome. He aquí un ejemplo:

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

Para activar: primer hijo y : reglas de último hijo descomentar los dos últimos elementos. La implementación de los selectores Nivel 3 estándar es por lo tanto inconsistente en los principales navegadores. La regla: primer hijo no debe activarse cuando existe una regla :hijo único y un hijo único tiene descendientes. En el ejemplo, el hijo único debe ser rojo, pero es verde.

 0
Author: user3483642,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-05 23:03:42