Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

238
Views
Cómo obtener todos los hermanos de un elemento principal con clases específicas en Vanilla JS

Tengo una larga lista de elementos de la lista (generados a través de una API) y me gustaría mostrar/ocultar algunos de los elementos con un clic, algo así como un efecto de acordeón.

Los elementos de la lista que me gustaría ocultar de forma predeterminada tienen una clase de elemento P , y la clase de elemento M sobre ellos es lo que debería activarlos para que se muestren.

Aquí está mi marcado:

 <li class="session-item M-item"></li> <li class="session-item P-item"></li> <li class="session-item P-item"></li> <li class="session-item G-item"></li>

Los artículos P son hijos de su artículo M principal. Entonces, de manera predeterminada en el ejemplo anterior, los dos elementos P deben estar ocultos y el elemento M y el elemento G deben mostrarse. Cuando se hace clic en el elemento M, se muestran los dos elementos P ocultos. Solo estoy enumerando 4 elementos en el ejemplo anterior, pero la lista continúa y el único separador entre esta relación son los elementos G.

Lo hice funcionar pero solo muestra/oculta el primer hermano directo de M-item, usé nextElementSibling , así:

 var acc = document.getElementsByClassName("M-item"); var i; for (i = 0; i < acc.length; i++) { acc[i].addEventListener("click", function () { this.classList.toggle("active"); var panel = this.nextElementSibling; if (panel.style.display === "block") { panel.style.display = "none"; } else { panel.style.display = "block"; } }); }

¿Cuál es la mejor manera de seleccionar a todos los hermanos con el elemento P y luego romper, buscar otro elemento M y repetir?

¿Hay algo similar a nextAll(); en vainilla JS? ¿Necesito un bucle while para iterar sobre el siguiente hermano?

Así es como se ve mi marcado completo:

ingrese la descripción de la imagen aquí

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

Mi respuesta parece un poco original, pero usa un ciclo while para ocultar todas las siguientes etiquetas <li> siempre que tengan la clase .P-item. El bucle se detiene si el siguiente elemento no tiene esa clase, por lo tanto, solo oculta los elementos P que siguen directamente al elemento M que se presionó. Pruébelo copiando y pegando todo el código siguiente aquí:

 <!DOCTYPE html> <head> <meta charset="utf-8"> <style> .M-item { background-color: red; color: blue; } .active { background-color: pink; } .hide { display: none; } </style> </head> <body> <ul class="agenda"> <li class="session-item M-item">something</li> <li class="session-item P-item">something</li> <li class="session-item P-item">something</li> <li class="session-item P-item">something</li> <li class="session-item M-item">something</li> <li class="session-item P-item">something</li> <li class="session-item P-item">something</li> <li class="session-item P-item">something</li> <li class="session-item P-item">something</li> <li class="session-item P-item">something</li> <li class="session-item M-item">something</li> <li class="session-item P-item">something</li> <li class="session-item P-item">something</li> <li class="session-item P-item">something</li> </ul> <script> var acc = document.getElementsByClassName("M-item"); var i; for (i = 0; i < acc.length; i++) { acc[i].addEventListener("click", function () { this.classList.toggle("active"); let next = this.nextElementSibling; while (next.classList.contains('P-item')) { next.classList.toggle('hide'); next = next.nextElementSibling; } }); } </script> </body> </html>
about 4 years ago · Juan Pablo Isaza Report

0

Creo que el OP tiene como objetivo encontrar hermanos adyacentes con la misma clase.

Una idea sería intervenir un poco antes, antes de que los li se configuren como hermanos, e imponer una estructura html allí, agrupando a los hermanos de clase similar en div (o ul ). Pero, si comenzamos con la lista ya construida, se puede manejar como una reducción en la colección de li 's...

 const sessionItems = document.getElementsByClassName("session-item"); let groups = Array.from(sessionItems).reduce((acc, el, index) => { const pItem = el.classList.contains("p-item") const delimeter = !pItem || index===0; if (delimeter) acc.push([]); if (pItem) acc[acc.length-1].push(el); return acc }, []); // now do whatever we want to the groups, like change visibility // for clarity in this example, add a color class groups.forEach((group, index) => { group.forEach(el => el.classList.add(`color-${index}`)) });
 .color-0 { color: red; } .color-1 { color: green; }
 <ul> <li class="session-item m-item">item A</li> <li class="session-item p-item">item B</li> <li class="session-item p-item">item C</li> <li class="session-item m-item">item D</li> <li class="session-item p-item">item E</li> <li class="session-item p-item">item F</li> <li class="session-item p-item">item G</li> <li class="session-item m-item">item H</li> </ul>

about 4 years ago · Juan Pablo Isaza Report

0

Puede mantener la visibilidad de los elementos P solo a través de CSS, según el "activo" que tenga el elemento M anterior. Esto significa que el código JS solo tiene que administrar la alternancia de la clase "activa" en el elemento M:

 const ul = document.querySelector(".cad-agenda"); ul.addEventListener("click", function (e) { const mItem = e.target; if (!mItem.classList.contains("M-item")) return; const wasActive = mItem.classList.contains("active"); document.querySelector(".active")?.classList?.remove("active"); mItem.classList.toggle("active", !wasActive); });
 .P-item { display: none } .active ~ .P-item:not(.active ~ .M-item ~ .P-item) { display: block } .M-item { cursor: pointer; font-weight: bold }
 <ul class="cad-agenda accordion accordion-1"> <li class="session-item M-item">M-1</li> <li class="session-item P-item">P-1.1</li> <li class="session-item P-item">P-1.2</li> <li class="session-item G-item">G-1</li> <li class="session-item M-item">M-2</li> <li class="session-item P-item">P-2.1</li> <li class="session-item P-item">P-2.2</li> <li class="session-item M-item">M-3</li> <li class="session-item P-item">P-3.1</li> <li class="session-item P-item">P-3.2</li> <li class="session-item Press-item">PressItem</li> <li class="session-item M-item">M-3</li> <li class="session-item P-item">P-3.1</li> <li class="session-item M-item">M-4</li> <li class="session-item P-item">P-4.1</li> <li class="session-item M-item">M-5</li> <li class="session-item P-item">P-5.1</li> <li class="session-item G-item">G-2</li> <li class="session-item M-item">M-6 (has no P)</li> <li class="session-item -item">empty 1</li> <li class="session-item -item">empty 2</li> <li class="session-item -item">empty 3</li> <li class="session-item M-item">M-7 (has no P)</li> <li class="session-item M-item">M-8</li> <li class="session-item P-item">P-8.1</li> <li class="session-item P-item">P-8.2</li> </ul>

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!