Necesito contar divs específicos y después de cada X divs inserto otro div con un párrafo. Todo en JavaScript puro.
Terminé de contar los divs específicos, pero no sé cómo manejar el ciclo e insertar el contenedor y el párrafo.
<div class="main">
<div class="special-div">div 1</div>
<div class="special-div">div 1</div>
<div class="special-div">div 1</div>
</div>
<script>
count = document.getElementsByClassName("special-div").length; // Output: X
</script>
Una instrucción for básica sería adecuada para este problema.
Use querySelectorAll en lugar de getElementsByClassName , ya que es más fácil de administrar: QSA devuelve una lista de nodejs estática similar a una matriz, mientras que gEBCN devuelve una colección HTML en vivo que puede hacer que se tropiece cuando comience a insertar nuevos elementos durante su iteración.
Para averiguar dónde debe agregar el nuevo elemento div, use el operador de resto (también llamado "módulo"). A medida que itera sobre la lista de nodejs, verifique si dividir el índice actual + 1 (las matrices se basan en cero) por el número especificado da como resultado cero. Si es así, agregue el nuevo elemento div after del actual.
Nota: he separado el código para crear un nuevo elemento div en una función para simplificar las cosas.
const divs = document.querySelectorAll('.special-div');
// Loop over the array-like structure that
// qsa returns. Find the remainder of dividing
// the index by the supplied `n` argument. If it's
// zero create a new div element and add it `after`
// the current div
function insertAfter(n, text) {
for (let i = 0; i < divs.length; i++) {
if ((i + 1) % n === 0) {
const div = createDiv(text);
divs[i].after(div);
}
}
}
// For convenience a function that creates
// a new paragragh element wrapped in a div.
// It uses the text passed in as an argument
function createDiv(text) {
const div = document.createElement('div');
div.className = 'special-div';
const para = document.createElement('p');
para.textContent = 'new!';
div.appendChild(para);
return div;
}
// Call the main function. The arguments are
// the count where you add a new div, and the
// text you want to appear in the paragraph
insertAfter(2, 'new!');
div.special-div p { color: red; }
<div class="main">
<div class="special-div">one</div>
<div class="special-div">two</div>
<div class="special-div">three</div>
<div class="special-div">four</div>
<div class="special-div">five</div>
<div class="special-div">six</div>
</div>
Esto itera los nodejs con la clase special-div , haciendo un seguimiento del índice. Para índices distintos de cero divisibles por interval , crea e inserta un nuevo div.
const interval = 3;
const parent = document.getElementById("parent");
const elements = [...document.getElementsByClassName("special-div")];
const divWithText = text => {
const newNode = document.createElement("div");
newNode.appendChild(document.createTextNode(text));
return newNode
};
elements.forEach((node,i) => {
if (i && i % interval === 0) {
parent.insertBefore(divWithText("new div"), node);
}
});
<div id="parent" class="main">
<div class="special-div">div 1</div>
<div class="special-div">div 1</div>
<div class="special-div">div 1</div>
<div class="special-div">div 1</div>
<div class="special-div">div 1</div>
<div class="special-div">div 1</div>
<div class="special-div">div 1</div>
<div class="special-div">div 1</div>
<div class="special-div">div 1</div>
<div class="special-div">div 1</div>
<div class="special-div">div 1</div>
<div class="special-div">div 1</div>
</div>
Lo siento, no estoy muy seguro de qué salida espera.
¿Qué tal usar .insertAdjacentHTML(<position>, <text>) ? Inserta código HTML en un elemento específico. No es necesario contar divs :)
element.insertAdjacentHTML()
element como main en mi código. posición: 'beforeend'
</div> de .main posición: 'afterend'
</div> de .special-div const main = document.querySelector('.main');
let html = `
<div>
<p>new</p>
</div>
`
// Insert html at the end of all children of .main
main.insertAdjacentHTML('beforeend', html);
<div class="main">
<div class="special-div">div 1</div>
<div class="special-div">div 1</div>
<div class="special-div">div 1</div>
</div>
const targetDivs = document.querySelectorAll('.special-div');
let html = `
<div>
<p>new</p>
</div>
`
// Insert html after every specific div
targetDivs.forEach(div => div.insertAdjacentHTML('afterend', html));
// you can't do this: targetDivs.insertAdjacent()
// Because targetDivs is a NodeList which is like an array [].
// You have to use .insertAdjacent() on every div one by one,
// not on an array(NodeList)
<div class="main">
<div class="special-div">div 1</div>
<hr>
<div>Ignore this div</div>
<hr>
<div class="special-div">div 1</div>
<hr>
<div class="special-div">div 1</div>
</div>