Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

235
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda