Si el elemento tiene hijos, inserte un nuevo div "i-new-element" . parent2 y parent3 obtienen un nuevo div.
child3-parent3 tiene hijos pero no obtiene un nuevo gigante. ¿Por qué?
¿Cómo puedo hacer posible que los niños que tienen hijos obtengan un nuevo div?
debería verse como:
<div id="child3-parent3"> <div id="i-new-element"></div> <div id="child3"></div> <div id="child4"></div> </div> var container = document.getElementById("container").querySelectorAll("#container > *"); container.forEach(function(div) { { if (div.hasChildNodes()) { let parentElement = div; let theFirstChild = parentElement.firstChild; let newElement = document.createElement("div") newElement.id = "i-new-eleemnt" parentElement.insertBefore(newElement, theFirstChild) } } }); <div id="container"> <div id="parent1"></div> <div id="parent2"> <div id="child1"></div> <div id="child2"></div> <div id="child3-parent3"> <div id="child3"></div> <div id="child4"></div> </div> </div> <div id="parent3"> <div id="child5"></div> <div id="child6"></div> </div> </div>Usando
var container = document.getElementById("container"); var elements = container.querySelectorAll(":scope *");en vez de
var container = document.getElementById("container").querySelectorAll("#container > *");debería solucionar su problema.
var container = document.getElementById("container"); var elements = container.querySelectorAll(":scope *"); elements.forEach(function(div){ { if (div.hasChildNodes()) { let parentElement = div; let theFirstChild = parentElement.firstChild; let newElement = document.createElement("div") newElement.id = "i-new-eleemnt" parentElement.insertBefore(newElement, theFirstChild) } } }); <div id="container"> <div id="parent1"></div> <div id="parent2"> <div id="child1"></div> <div id="child2"></div> <div id="child3-parent3"> <div id="child3"></div> <div id="child4"></div> </div> </div> <div id="parent3"> <div id="child5"></div> <div id="child6"></div> </div> </div> Editar : Puede encontrar más información sobre la pseudoclase CSS de :scope aquí y aquí .
Creo que su problema es el siguiente, aunque no se describe bien en su HTML de muestra:
<div id="parent1"></div> por instancia en realidad no es un nodo vacío pero contiene algo de texto, es decir, <div id="parent1">some text here</div> .
Puede creerlo o no, pero node.hasChildNodes() contará cualquier texto como un nodo secundario (nodo de texto, tipo de nodo = 3), por lo que siempre devolverá true si hay texto presente.
Para evitar eso, puede filtrar los nodos de texto primero o simplemente usar esta solución alternativa:
Reemplace esta línea:
if (div.hasChildNodes()) {con esa línea:
if (div.children.length) {La propiedad children no cuenta los nodos de texto.
Eso es todo lo que tienes que hacer, creo.
var container = document.querySelectorAll("#container > *"); container.forEach(function(div) { { if (div.children.length) { let parentElement = div; let theFirstChild = parentElement.children[0]; let newElement = document.createElement("div") newElement.id = "i-new-eleemnt"; newElement.innerHTML = 'i-new-eleemnt' parentElement.insertBefore(newElement, theFirstChild); } } }); <div id="container"> <div id="parent1">parent1</div> <div id="parent2">parent2 <div id="child1">child1</div> <div id="child2">child2</div> <div id="child3-parent3">child3-parent3 <div id="child3">child3</div> <div id="child4">child4</div> </div> </div> <div id="parent3">parent3 <div id="child5">child5</div> <div id="child6">child6</div> </div> </div>