2012-02-05 13 views
15

¿Hay alguna manera de cambiar un atributo de una clase CSS mediante javascript?Cambiar el estilo de una clase completa de CSS mediante javascript

<style type="text/css"> 
    .fool select { 
    display: block; 
    } 
</style> 

<p class="fool"> 
    <select id="a" onchange="changeCSS()"> ... </select> 
    <select id="b" > ... </select> 
    <select id="c" > ... </select> 
</p> 

que quieren cambiar display: block a display: none para TODOS los elementos <select> después de un changeCSS función de llamada de usuario().

Parece simple, pero no puedo encontrar una manera de hacer esto ...

+0

duplicado Posible de http://stackoverflow.com/questions/622122/how-can-i-change-the-css -class-rules-using-jquery – j08691

+7

@ j08691: No, esa pregunta es acerca de ** jQuery **. Este no presupone su uso de esa biblioteca. –

+0

Puede consultar este sitio http://quirksmode.org/dom/w3c_css.html – Michas

Respuesta

11

La clave es definir reglas adicionales para clases adicionales y un dd estas clases a los elementos en lugar de reescribir las reglas para una regla de estilo determinada.

JS

function changeCSS() { 
    var selects = document.getElementsByTagName("select"); 
    for(var i =0, il = selects.length;i<il;i++){ 
    selects[i].className += " hidden"; 
    } 
} 

CSS

.fool select.hidden, select.hidden { 
    display: none; 
} 

O para un método muy eficiente (pero que podría necesitar algunas reglas de estilo más específicas también)

JS

function changeCSS() { 
    document.getElementsByTagName("body")[0].className += " hideAllSelects" 
} 

CSS

body.hideAllSelects select { 
    display: none; 
} 
+1

¡Gracias! Esto funciona para mí: var selecciona = document.getElementsByTagName ("select"); for (var i = 0, il = selects.length; i Bedo

1

Para obtener el mismo efecto, puede hacer otro estilo:

<style type="text/css"> 
    .fool select { 
    display: block; 
    } 
    .foolnone select { 
    display: none; 
    } 
</style> 

y cambiar la clase de <p> a foolnone.

De lo contrario, tendría que pasar por cada uno de los hijos de <p> y cambiar la clase. Si esa es la forma en que desea ir, probablemente sea mejor usar alguna biblioteca, como jquery. Con él, usted puede hacer algo como:

<style> 
.fool select.displaynone { 
    display: none 
} 

$('.fool>select').toggleClass('displaynone') 

Ver este jsFiddle para un ejemplo de trabajo:

Esto demuestra ambos enfoques anteriores (es decir, ocultando toda la <p> y ocultar cada uno de los <select> s.

+0

Siempre preferiría agregar otra clase y definir una regla de estilo diferente con un selector más largo, en lugar de cambiar la clase ya que la clase existente "tonto" podría ser usado para otras cosas también y puede que no sea seguro eliminarlo por completo – wheresrhys

+0

@wheresrhys Completamente de acuerdo - vea el ejemplo que agregué, mostrando ambos enfoques. Agrega la clase 'displaynone' para esto. Sin embargo, eso encaja en su proyecto es algo en lo que puede reflexionar, pero esto debería ser lo que puede utilizar básicamente, dejando de lado los detalles. –

-1
for(var elements = document.getElementsByTagName('select'), i = elements.length; i--) 
    elements[i].style.display = "none"; 
+0

No funciona (incluso reemplazando "," con ";" antes de "i = ..." Este es el error: "UnEdge TypeError: No se puede leer la propiedad 'style' of undefine" – Bedo

9

Usted puede modificar las reglas de estilo, pero no es por lo general la mejor decisión de diseño.

Para acceder a las reglas de estilo definidas por las hojas de estilo, tiene acceso a la colección document.styleSheets. Cada entrada en esa colección tendrá una propiedad llamada cssRules o rules dependiendo del navegador. Cada uno de esos será una instancia CSSRule. Puede cambiar la regla cambiando su propiedad cssText.

Pero de nuevo, esa no es probablemente la mejor manera de resolver el problema. Pero es la respuesta literal a tu pregunta.

La mejor manera de resolver el problema es probablemente tener otra clase en su hoja de estilo que anule la configuración de la regla anterior y luego agregar esa clase a los elementos select o al contenedor de ellos. Así, por ejemplo, usted podría tener las reglas:

.fool select { 
    display: block; 
} 
.fool.bar select { 
    display: none; 
} 

... y cuando se desea ocultar los selecciona, añadir la clase "bar" al contenedor que tiene la clase "fool".

Como alternativa, aplique información de estilo CSS directamente a los elementos.

+3

Modificar las reglas tiene sentido donde hay una gran cantidad de elementos con los que debe cambiar la clase, es mucho más rápido que cambiar los elementos uno por uno (que es lo que debe hacer cualquier función basada en el selector). Delegar cambios a un elemento primario también es bastante rápido. – RobG

+0

Perfecto, buena respuesta - explica, que en general no es la mejor decisión, pero en lugar de tratar de prohibir algo por razones filosóficas, más bien explica, cómo hacer esto si fuera necesario. Un ejemplo, ya que podría ser útil: usted tiene una muchos objetos en el DOM, y la modificación de la clase (y que el recuento duro funcione en el código C++ del navegador) resulta en una mejor aplicación, como el bucle de los elementos por selector de clase (y haciendo la h ard trabajo de JS). – peterh

+0

@peterh: Sí, aunque la última vez que probé esto (hace unas semanas, tratando de responder una pregunta diferente), parecía que las reglas se habían convertido en de solo lectura. Nunca tuve tiempo de dar seguimiento a eso ... –

11

Estoy accediendo a las clases de CSS directamente para ajustar la altura de un grupo de divs simultáneamente. Así es como lo estoy haciendo:

function cssrules(){ 
    var rules={}; var ds=document.styleSheets,dsl=ds.length; 
    for (var i=0;i<dsl;++i){ 
    var dsi=ds[i].cssRules,dsil=dsi.length; 
    for (var j=0;j<dsil;++j) rules[dsi[j].selectorText]=dsi[j]; 
    } 
    return rules; 
}; 
function css_getclass(name,createifnotfound){ 
    var rules=cssrules(); 
    if (!rules.hasOwnProperty(name)) throw 'todo:deal_with_notfound_case'; 
    return rules[name]; 
}; 

y entonces usted puede hacer algo como css_getclass('.classname').style.background="blue". Solo probé esto en Chrome para Windows, buena suerte con otros navegadores.

+1

Esto funcionó bien en firefox 21, opera 12.12 y es decir, 10 también.Las reglas de selector más elaboradas también funcionan. 'css_getclass ('td: first-child a img'). Style.width = this.value +" em ";' – Stephen

+0

Nota por compatibilidad necesita cambiar 'dsi = ds [i] .cssRules' a' dsi = ds [i] .cssRules || ds [i] .rules' y tenga en cuenta que la función sobreescribirá las reglas si existe el mismo texto de selección en una styleSheet anterior. – aMarCruz

0

Así es como yo lo haría:

//Broken up into multiple lines for your convenience 
 
setTimeout 
 
(
 
    function() 
 
    { 
 
    document.getElementById('style').innerHTML = 'p.myclass{display: none}'; 
 
    }, 5000 
 
);
<!--Should this be separated into "<head>"?--> 
 
<style id="style"></style> 
 

 
<p>After 5 seconds:</p> 
 
<p>This text won't be hidden,</p> 
 
<p class="myclass">But this will,</p> 
 
<p class="myclass">And so will this.</p> 
 

 
<script> 
 
\t style = document.getElementById('style'); 
 
\t setTimeout(function(){style.innerHTML = 'p.myclass{display: none}'}, 5000); 
 
</script>

Cuestiones relacionadas