2012-02-05 16 views
15

C'è un modo per cambiare un attributo di una classe CSS usando javascript?Cambia lo stile di un'intera classe CSS usando 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> 

voglio cambiare display: block a display: none per TUTTI <select> elementi dopo una chiamata di funzione utente changeCSS().

Sembra semplice, ma non riesco a trovare un modo per fare questo ...

+0

Eventuali duplicati di http://stackoverflow.com/questions/622122/how-can-i-change-the-css -class-rules-using-jquery – j08691

+7

@ j08691: No, la domanda riguarda ** jQuery **. Questo non suppone il tuo uso di quella libreria. –

+0

È possibile visualizzare questo sito http://quirksmode.org/dom/w3c_css.html – Michas

risposta

11

La chiave è definire regole aggiuntive per classi aggiuntive e un dd queste classi agli elementi piuttosto che riscrivere le regole per una determinata regola di stile.

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 per un metodo davvero efficace (ma che potrebbe aver bisogno di alcune regole di stile più specifiche troppo)

JS

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

CSS

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

Grazie! Questo funziona per me: var select = document.getElementsByTagName ("select"); per (var i = 0, il = selects.length; i Bedo

1

Per ottenere lo stesso effetto, si può fare un altro stile:

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

e cambiare la classe di <p> a foolnone.

Altrimenti, dovresti passare attraverso ciascuno dei figli di <p> e cambiare classe. Se questo è il modo in cui vuoi andare, probabilmente probabilmente è meglio usare qualche libreria, come ad esempio jquery. Con esso, si può fare qualcosa di simile:

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

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

Vedere questo jsfiddle per un esempio di lavoro:

Questo dimostra entrambi gli approcci di cui sopra (cioè si nasconde tutta la <p> e nascondere ognuno di <select> s.

+0

Preferirei sempre aggiungere un'altra classe e definire una regola di stile diversa usando un selettore più lungo, piuttosto che cambiare la classe come potrebbe essere il "matto" della classe esistente usato anche per altre cose e potrebbe non essere sicuro rimuoverlo interamente – wheresrhys

+0

@wheresrhys Completamente d'accordo - vedi l'esempio che ho aggiunto, mostrando entrambi gli approcci. Aggiunge la classe 'displaynone' per questo. Tuttavia, quello che si adatta al tuo progetto è qualcosa su cui puoi riflettere, ma questo dovrebbe essere quello che puoi usare fondamentalmente, i dettagli a parte. –

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

Non funziona (anche sostituendo "," con ";" prima di "i = ..." Questo è l'errore: "Uncaught TypeError: Impossibile leggere la proprietà 'style' di undefine" – Bedo

9

È possibile modificare le regole di stile, ma non è di solito la migliore decisione di progettazione.

Per accedere alle regole di stile definite dai fogli di stile, è possibile accedere alla raccolta document.styleSheets. Ogni voce in quella raccolta avrà una proprietà chiamata cssRules o rules a seconda del browser. Ciascuno di quelli sarà un'istanza CSSRule. Puoi cambiare la regola cambiando la sua proprietà cssText.

Ma ancora, probabilmente non è il modo migliore per risolvere il problema. Ma è la risposta letterale alla tua domanda.

Il modo migliore per risolvere il problema è probabilmente quello di avere un'altra classe nel foglio di stile che sovrascrive le impostazioni della regola precedente e quindi aggiungere tale classe agli elementi select o al contenitore di essi. Così, per esempio, si potrebbe avere le regole:

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

... e quando si desidera nascondere le seleziona, aggiungere la classe "bar" al contenitore che ha la classe "fool".

In alternativa, applicare le informazioni di stile CSS direttamente agli elementi.

+3

La modifica delle regole ha senso dove c'è un gran numero di elementi con la classe da cambiare, è molto più veloce di cambiare gli elementi uno ad uno (che è quello che deve fare qualsiasi funzione basata sul selettore). Anche la delega delle modifiche a un genitore è abbastanza veloce. – RobG

+0

Perfetta buona risposta - spieghi, che per lo più non è la decisione migliore, ma invece di cercare di proibire qualcosa su ragioni filosofiche, piuttosto spiega, come farlo se fosse necessario. Un esempio, come potrebbe essere utile: tu hai un molti oggetti nel DOM e modificare la classe (e lasciare che il conteggio duro funzioni con il codice C++ del browser) risulta un'app migliore, come il looping degli elementi per selettore di classe (e facendo la h lavoro ardente da JS). – peterh

+0

@peterh: Sì, anche se l'ultima volta che ho provato questo (alcune settimane fa, cercando di rispondere a una domanda diversa), sembrava che le regole fossero diventate di sola lettura. Non ho mai avuto il tempo di seguirlo ... –

11

Accedo direttamente alle classi CSS per regolare l'altezza di un gruppo di div contemporaneamente. Questo è come lo sto facendo:

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]; 
}; 

e allora si può fare qualcosa di simile css_getclass('.classname').style.background="blue". Ho solo provato questo su Chrome per Windows, buona fortuna con altri browser.

+1

Questo ha funzionato bene in firefox 21, opera 12.12 e cioè 10 pure.Funzionano anche regole di selezione più elaborate. 'css_getclass ('td: first-child a img'). Style.width = this.value +" em ";' – Stephen

+0

Nota per compatibilità è necessario modificare 'dsi = ds [i] .cssRules' in' dsi = ds [i] .cssRules || ds [i] .rules' e sii consapevole che la funzione sovrascriverà le regole se lo stesso selectorText esiste in un precedente StyleSheet. – aMarCruz

0

Ecco come lo farei:

//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>

Problemi correlati