Seleccionar clases después de un elemento concreto en Javascript

  • Autor Autor kraciboy
  • Fecha de inicio Fecha de inicio
K

kraciboy

Beta
¡Usuario con pocos negocios! ¡Utiliza siempre saldo de Forobeta!
Buenas,

Llevo dandole vueltas bastantes horas y no consigo dar con la solución, a ver si algún buen conocedor de Javascript me puede hechar una mano. El tema reside en que dispongo de la siguiente una estructura similar a esta:

Insertar CODE, HTML o PHP:
[COLOR="#0000CD"]<li id="nombre-id"><div class="miClase">Titular 1</div></li>[/COLOR]
[COLOR="#B22222"]<li id="nombre-id"><div class="otraClase">Texto</div></li>
<li id="nombre-id"><div class="otraClase">Texto</div></li>
<li id="nombre-id"><div class="otraClase">Texto</div></li>
<li id="nombre-id"><div class="otraClase">Texto</div></li>
<li id="nombre-id"><div class="otraClase">Texto</div></li>[/COLOR]

[COLOR="#0000CD"]<li id="nombre-id"><div class="miClase">Titular 2</div></li>[/COLOR]
[COLOR="#B22222"]<li id="nombre-id"><div class="otraClase">Texto</div></li>
<li id="nombre-id"><div class="otraClase">Texto</div></li>
<li id="nombre-id"><div class="otraClase">Texto</div></li>
<li id="nombre-id"><div class="otraClase">Texto</div></li>
<li id="nombre-id"><div class="otraClase">Texto</div></li>[/COLOR]

[COLOR="#0000CD"]<li id="nombre-id"><div class="miClase">Titular 3</div></li>[/COLOR]
[COLOR="#B22222"]<li id="nombre-id"><div class="otraClase">Texto</div></li>
<li id="nombre-id"><div class="otraClase">Texto</div></li>
<li id="nombre-id"><div class="otraClase">Texto</div></li>
<li id="nombre-id"><div class="otraClase">Texto</div></li>
<li id="nombre-id"><div class="otraClase">Texto</div></li>[/COLOR]

Es un gestor que mete todo tal cual, lo único que puedo hacer es insertar entre <li id="nombre-id"></li> el contenido HTML que yo quiera

Al grano, lo que realmente me gustaría hacer es usar selectores en javascript, ya que vía CSS no se puede hacer. Lo que querría hacer que todos los elementos que están después de <div class="miClase">Titular 2</div> es decir los <li id="nombre-id"><div class="otraClase">Texto</div></li> cambiase la clase a "selected" por ejemplo y que dejase de cambiar la clase cuando encontrase su propia clase otra vez <div class="miClase">Titular 2</div>, una vez la encontrase otra vez, que volviese a hacer con los elementos

Quedando algo así:
Insertar CODE, HTML o PHP:
[COLOR="#0000CD"]<li id="nombre-id"><div class="miClase">Titular 1</div></li>[/COLOR]
[COLOR="#B22222"]<li id="nombre-id"><div class="otraClase">Texto</div></li>
<li id="nombre-id"><div class="otraClase nuevaClase">Texto</div></li>
<li id="nombre-id"><div class="otraClase nuevaClase">Texto</div></li>
<li id="nombre-id"><div class="otraClase nuevaClase">Texto</div></li>
<li id="nombre-id"><div class="otraClase nuevaClase">Texto</div></li>[/COLOR]

[COLOR="#0000CD"]<li id="nombre-id"><div class="miClase">Titular 2</div></li>[/COLOR]
[COLOR="#B22222"]<li id="nombre-id"><div class="otraClase">Texto</div></li>
<li id="nombre-id"><div class="otraClase nuevaClase">Texto</div></li>
<li id="nombre-id"><div class="otraClase nuevaClase">Texto</div></li>
<li id="nombre-id"><div class="otraClase nuevaClase">Texto</div></li>
<li id="nombre-id"><div class="otraClase nuevaClase">Texto</div></li>[/COLOR]

[COLOR="#0000CD"]<li id="nombre-id"><div class="miClase">Titular 3</div></li>[/COLOR]
[COLOR="#B22222"]<li id="nombre-id"><div class="otraClase">Texto</div></li>
<li id="nombre-id"><div class="otraClase nuevaClase">Texto</div></li>
<li id="nombre-id"><div class="otraClase nuevaClase">Texto</div></li>
<li id="nombre-id"><div class="otraClase nuevaClase">Texto</div></li>
<li id="nombre-id"><div class="otraClase nuevaClase">Texto</div></li>[/COLOR]

Lo he intentado con jQuery con las funciones nextAll(); y nextUntil(); pero no consigo dar con ello, tampoco soy un experto en javascript, por eso pido ayuda, por si a alguien se le ocurre la forma de hacer lo que tengo pensado o si por el contrario no se puede hacer

Muchas gracias de antemano
Un saludo!
 
1ero: Las id DEBEN ser únicas, por eso son IDs. Que todos tus <li> tengan el mismo ID está mal hecho.

2do:

(".otraClase").addClass("nuevaClase");

¿No te sirve?

No entiendo bien que es lo que necesitas 😵
 
Si, son id's unicas, cuando digo id="nombre-id" me refiero a que son consecutivos, id="nombre-1", id="nombre-2", etc... Loque quiero hacer es seleccionar todos los elementos que estan por debajo del titulo cambien a la clase A, cuando llegue a otro titulo los elementos cambien a la clase B y así sucesivamente. Es dificil de explicar, pero puedo intentar hacer un crokis en photoshop y así lo aclaro un poco mejor

Enviado desde mi Nexus 4 usando Tapatalk 2
 
Si, son id's unicas, cuando digo id="nombre-id" me refiero a que son consecutivos, id="nombre-1", id="nombre-2", etc... Loque quiero hacer es seleccionar todos los elementos que estan por debajo del titulo cambien a la clase A, cuando llegue a otro titulo los elementos cambien a la clase B y así sucesivamente. Es dificil de explicar, pero puedo intentar hacer un crokis en photoshop y así lo aclaro un poco mejor

Enviado desde mi Nexus 4 usando Tapatalk 2

Este es el codigo que buscas:

Insertar CODE, HTML o PHP:
$(function() {    var cont = 0;
    var class_to_assign = "";
    var cont_changed = false;


    $("li").each(function() {
            if($(this).find("div").hasClass("miClase")) {
                cont += 1;
                cont_changed = !cont_changed;
            } else {
                if(cont_changed) {
                    switch(cont) {
                        case 1: class_to_assign = "nuevaA";
                            break;
                        case 2: class_to_assign = "nuevaB";
                            break;
                        case 3: class_to_assign = "nuevaC";
                            break;
//Aqui agregas tantos casos como divs con [COLOR=#0000CD]miClase[/COLOR] tengas
                            default: class_to_assign = "";
                            break;
                    }
                    cont_changed = !cont_changed;
                }
                $(this).find("div").addClass(class_to_assign);
            } 
        });    
});

Si tus <li> estan dentro de algun div o span con un id="miID" solo cambia la siguiente linea de:
Insertar CODE, HTML o PHP:
$("li").each(function() {
A:
Insertar CODE, HTML o PHP:
$("#miID li").each(function() {
 
Última edición:
Parece que has dado con la solución, he realizado la prueba en JSfiddle y parece que está correcto, en un rato lo aplicaré en mi sitio. Dejo el ejemplo que me has pasado en funcionamiento aquí

Edit this Fiddle - jsFiddle

Muchas gracias por tu ayuda!
Un saludo!
 
Parece que has dado con la solución, he realizado la prueba en JSfiddle y parece que está correcto, en un rato lo aplicaré en mi sitio. Dejo el ejemplo que me has pasado en funcionamiento aquí

Edit this Fiddle - jsFiddle

Muchas gracias por tu ayuda!
Un saludo!

Ahí mismo lo probé yo :B

Si en su lugar puedes hacer que los nombres de las clases nuevas sean "claseA", "claseB" y así el código se simplificaría bastante, quitaríamos todo ese Switch 😉

Sería algo como:

Insertar CODE, HTML o PHP:
$(function() {    
    var cont = 64;    
    var class_to_assign = "";
    var cont_changed = false;

    $("li").each(function() {
            if($(this).find("div").hasClass("miClase")) {
                cont += 1;
                cont_changed = !cont_changed;
            } else {
                if(cont_changed) {
                    class_to_assign = "clase" + String.fromCharCode(cont);
                    cont_changed = !cont_changed;
                }
                $(this).find("div").addClass(class_to_assign);
            } 
        });    
});

Inicializamos cont en 64, pues sumandole 1 al pasar por el primer "miClase" tenemos 65, que es el codigo ASCII de la letra A
 
Ahí mismo lo probé yo :B

Si en su lugar puedes hacer que los nombres de las clases nuevas sean "claseA", "claseB" y así el código se simplificaría bastante, quitaríamos todo ese Switch 😉

Sería algo como:

Insertar CODE, HTML o PHP:
$(function() {    
    var cont = 64;    
    var class_to_assign = "";
    var cont_changed = false;

    $("li").each(function() {
            if($(this).find("div").hasClass("miClase")) {
                cont += 1;
                cont_changed = !cont_changed;
            } else {
                if(cont_changed) {
                    class_to_assign = "clase" + String.fromCharCode(cont);
                    cont_changed = !cont_changed;
                }
                $(this).find("div").addClass(class_to_assign);
            } 
        });    
});

Inicializamos cont en 64, pues sumandole 1 al pasar por el primer "miClase" tenemos 65, que es el codigo ASCII de la letra A

Funciona correctamente con dicho metodo y mucho mejor, ya que dejaría realizadas las clases de la A-Z y solucionado, dudo mucho que fuese a usar todas las letras del abecedario, pero por si las "moscas"

Para rematar de la faena, si pudiese, me gustaría ponerle un botón dentro del "<li id="nombre-id"><div class="miClase">Titular 2</div></li>" para hacer de acordeón con el contenido que hay dentro, es decir, al pulsar el botón ocultar el contenido de la claseA o mostrarlo, lo mismo con claseB, claseC, etc... y a ver si consigo que al cargar la página, por defecto se quede abierto el primero o todos por defecto "collapsed"

EDITO: De momento lo he conseguido metiendo los botones a mano mano http://jsfiddle.net/BFGZp/7/. Aunque me he dado cuenta que el hide(); no vale puesto que me esconde todas las cajas ya tengan la clase claseA, claseB como si tiene una clase "fulanito"

Muchas gracias por todo
Un saludo!
 
Última edición:
Creo que así quedaría lo que quieres (modifiqué un par de cosas del código ese) Edit this Fiddle - jsFiddle

Así solo sale abierto el primero y se ocultan también los puntitos (los li, porque antes solo ocultaba los div de dentro).

Un saludo 😉

Edito: Si quieres que se muestren todos al principio quita de la última línea larga: .not('.claseA').parent().hide('normal') dejando que termine en ; y listo.
 
Última edición:
Creo que así quedaría lo que quieres (modifiqué un par de cosas del código ese) Edit this Fiddle - jsFiddle

Así solo sale abierto el primero y se ocultan también los puntitos (los li, porque antes solo ocultaba los div de dentro).

Un saludo 😉

Edito: Si quieres que se muestren todos al principio quita de la última línea larga: .not('.claseA').parent().hide('normal') dejando que termine en ; y listo.

Gracias a ambos por vuestra ayuda, sin ella no lo hubiese conseguido, al final lo he dejado de la siguiente forma Edit this Fiddle - jsFiddle

Ya que de la anterior tenía un problema, era que al meter el hide(); en la última linea me ocultaba todos los divs que hubiesen dentro que no fuesen dicha clase tanto siendo padres como hijos, por lo que lo hice de la forma anteriormente detallada

Un saludo!
 
Atrás
Arriba