Puedo hacer esto:
<div id="myDiv">
<div class="foo"></div>
</div>
myDiv = getElementById("myDiv");
myDiv.querySelectorAll("#myDiv > .foo");
Es decir, puedo recuperar con éxito todos los hijos directos del myDivelemento que tienen clase .foo.
El problema es que me molesta que deba incluir el #myDiven el selector, porque estoy ejecutando la consulta en el myDivelemento (por lo que obviamente es redundante).
Debería poder dejar la opción #myDivdesactivada, pero entonces el selector no es una sintaxis legal ya que comienza con >.
¿Alguien sabe cómo escribir un selector que obtenga solo los hijos directos del elemento en el que se está ejecutando el selector?
javascript
dom
css-selectors
mattsh
fuente
fuente

Respuestas:
Buena pregunta. En el momento en que se solicitó, no existía una forma implementada universalmente para realizar "consultas con raíz de combinador" (como las llamó John Resig ).
Ahora se ha introducido la pseudoclase: scope . No es compatible con las versiones [anteriores a Chrominum] de Edge o IE, pero Safari ya lo ha admitido durante algunos años. Usando eso, su código podría convertirse en:
Tenga en cuenta que, en algunos casos, también puede omitir
.querySelectorAlly utilizar otras características de la API DOM antiguas. Por ejemplo, en lugar demyDiv.querySelectorAll(":scope > *")simplemente escribirmyDiv.children, por ejemplo.De lo contrario, si aún no puede confiar
:scope, no puedo pensar en otra forma de manejar su situación sin agregar más lógica de filtro personalizada (por ejemplo, encontrar demyDiv.getElementsByClassName("foo")quién.parentNode === myDiv), y obviamente no es ideal si está tratando de admitir una ruta de código que realmente ¡solo quiere tomar una cadena de selección arbitraria como entrada y una lista de coincidencias como salida! Pero si, como yo, terminaste haciendo esta pregunta simplemente porque te quedaste atascado pensando "todo lo que tenías fue un martillo", no olvides que hay una variedad de otras herramientas que DOM también ofrece.fuente
myDiv.getElementsByClassName("foo")no es lo mismo quemyDiv.querySelectorAll("> .foo"), es más parecidomyDiv.querySelectorAll(".foo")(que en realidad funciona, por cierto) en el sentido de que encuentra todos los descendientes.fooen lugar de solo los hijos.<style scoped>) no tienen nada que ver con el:scopepseudo-selector descrito en esta respuesta.La forma correcta de escribir un selector que está "arraigado" al elemento actual es usar
:scope.Sin embargo, la compatibilidad con el navegador es limitada y necesitará una cuña si desea utilizarla. Construí scopedQuerySelectorShim para este propósito.
fuente
:scopeespecificación es actualmente un "Borrador de trabajo" y, por lo tanto, está sujeta a cambios. Es probable que siga funcionando así si / cuando se adopte, pero un poco antes de decir que esta es la "forma correcta" de hacerlo en mi opinión.Aquí hay un método flexible, escrito en vanilla JS, que le permite ejecutar una consulta de selector de CSS solo sobre los hijos directos de un elemento:
fuente
Math.random().toString(36).substr(2, 10)producir la misma ficha más de una vez.any dupe would need to also be a child of the same parent node,idatributos son en todo el documento. Tienes razón, las probabilidades siguen siendo bastante insignificantes, pero gracias por tomar el camino correcto y agregar ese contador :)si sabe con certeza que el elemento es único (como su caso con el ID):
Para una solución más "global": (use un ajuste de MatchSelector )
donde
elmestá su elemento padre yseles su selector. También se podría utilizar totalmente como prototipo.fuente
matchesSelectorprefijo (que ni siquiera funciona en la última versión de Chrome), contamina el espacio de nombres global (no se declaró ret), no devuelve una NodeList como se espera que haga querySelectorMethods. No creo que sea una buena solución, de ahí el voto negativo.La siguiente solución es diferente a las propuestas hasta ahora y me funciona.
La razón es que primero selecciona todos los hijos coincidentes y luego filtra los que no son hijos directos. Un hijo es un hijo directo si no tiene un padre que coincida con el mismo selector.
HTH!
fuente
Creé una función para manejar esta situación, pensé en compartirla.
En esencia, lo que está haciendo es generar una cadena aleatoria (la función randomString aquí es un módulo npm importado, pero puede crear el suyo) y luego usar esa cadena aleatoria para garantizar que obtiene el elemento que espera en el selector. Entonces eres libre de usar el
>después de eso.La razón por la que no estoy usando el atributo id es que es posible que el atributo id ya esté en uso y no quiero anularlo.
fuente
Bueno, podemos obtener fácilmente todos los hijos directos de un elemento usando
childNodesy podemos seleccionar ancestros con una clase específica conquerySelectorAll, por lo que no es difícil imaginar que podríamos crear una nueva función que obtenga ambos y los compare.Nota: Esto devolverá una matriz de nodos, no una NodeList.
Uso
fuente
Me gustaría agregar que puede extender la compatibilidad de : scope simplemente asignando un atributo temporal al nodo actual.
fuente
Me hubiera ido con
fuente
Estoy haciendo esto sin siquiera intentarlo. ¿Funcionaría esto?
Pruébelo, tal vez funcione, tal vez no. Disculpas, pero ahora no estoy en una computadora para probarlo (respondiendo desde mi iPhone).
fuente