Seleccionar clases después de un elemento concreto en Javascript

kraciboy Seguir

Beta
¡Usuario con pocos negocios! ¡Utiliza siempre saldo de Forobeta!
Desde
16 Jun 2009
Mensajes
51
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!
 

Brandon Díaz

Lambda
SEO
Verificación en dos pasos activada
Desde
24 Nov 2011
Mensajes
2.815
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 o_O
 

kraciboy

Beta
¡Usuario con pocos negocios! ¡Utiliza siempre saldo de Forobeta!
Desde
16 Jun 2009
Mensajes
51
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
 

Brandon Díaz

Lambda
SEO
Verificación en dos pasos activada
Desde
24 Nov 2011
Mensajes
2.815
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:

kraciboy

Beta
¡Usuario con pocos negocios! ¡Utiliza siempre saldo de Forobeta!
Desde
16 Jun 2009
Mensajes
51
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!
 

Brandon Díaz

Lambda
SEO
Verificación en dos pasos activada
Desde
24 Nov 2011
Mensajes
2.815
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
 

kraciboy

Beta
¡Usuario con pocos negocios! ¡Utiliza siempre saldo de Forobeta!
Desde
16 Jun 2009
Mensajes
51
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:

gamarro

Beta
Verificado por Whatsapp
¡Usuario con pocos negocios! ¡Utiliza siempre saldo de Forobeta!
Desde
26 Sep 2012
Mensajes
43
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:

kraciboy

Beta
¡Usuario con pocos negocios! ¡Utiliza siempre saldo de Forobeta!
Desde
16 Jun 2009
Mensajes
51
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!
 
Arriba