2010-04-25 18 views
6

Im avere problemi con questa funzione l'applicazione di css (utilizzando una variabile di testo) che lavorano con Internet Explorer ma funziona in Firefox & Chrome.controllo css con javascript funziona con Mozilla e Chrome, ma non IE

the code:

/*! addCssStyle() applies the text value $CssText$ to the the specified document 
$Doc$ e.g. an IFrame; or if none specified, default to the current document, 
*/function addCssStyle(CssText, Doc){ 

//Secure $Head$ for the current $Doc$ 
    Doc = Doc||document; var head = Doc.getElementsByTagName('head')[0]; 
    if(!head || head == null){ 
     head = Doc.createElement('div'); Doc.body.appendChild(head); 
    } if(!head || head == null){return false;} 

//createElement('style') 
    var PendingStyle = Doc.createElement('style'); 
// if (is_gecko){PendingStyle.href = 'FireFox.css';}//???needeed??? 
    PendingStyle.type = 'text/css'; 
    PendingStyle.rel = 'stylesheet'; 
// PendingStyle.media = 'screen';//???needeed??? 
    PendingStyle.innerHTML = CssText; 
    head.appendChild(PendingStyle); 

}/*___________________________________________________________________________*/ 

the use of the function:

var NewSyleText = //The page styling 
"h1, h2, h3, h4, h5 {font-family: 'Verdana','Helvetica',sans-serif; font-style: normal; font-weight:normal;}" + 
"body, b {background: #fbfbfb; font-style: normal; font-family: 'Cochin','GaramondNo8','Garamond','Big Caslon','Georgia','Times',serif;font-size: 11pt;}" + 
"p { margin: 0pt; text-indent:2.5em; margin-top: 0.3em; }" + 
"a { text-decoration: none; color: Navy; background: none;}" + 
"a:visited { color: #500050;}" + 
"a:active { color: #faa700;}" + 
"a:hover { text-decoration: underline;}"; 
addCssStyle(NewSyleText);//inserts the page styling 
+1

perché si vuole aggiungere css del genere? –

+2

@Ken bene ogni richiesta di file a un server è più onerosa sul server rispetto ai file separati. Inoltre ero annoiato. – GlassGhost

+1

Sono contento che questa sia una domanda interessante; altrimenti, sarei tentato di revocarlo solo per "Plus, ero annoiato". :-D –

risposta

3
var style = document.createElement('style'); 

Aggiunta di nuovi fogli di stile e script da elementi che creano con metodi DOM è qualcosa che è sempre stato rischioso cross-browser. Questo non funzionerà in IE o WebKit.

style.rel = 'stylesheet'; 
style.href = 'FireFox.css'; 

Non esistono tali proprietà su un HTMLStyleElement. <style> contiene codice inline. Per i fogli di stile esterni, utilizzare <link>. Per fortuna, succede che funziona:

var link= document.createElement('link'); 
link.rel= 'stylesheet'; 
link.href= 'something.css'; 
head.appendChild(link); 

Ma non ti dà un modo conveniente per inserire le regole dallo script.

È inoltre possibile aggiungere nuove regole a un foglio di stile esistente (ad esempio, un style vuoto nel <head>) utilizzando l'interfaccia document.styleSheets. Purtroppo, l'interfaccia di IE non corrispondono del tutto alla norma qui quindi è necessario il codice di diramazione:

var style= document.styleSheets[0]; 
if ('insertRule' in style) 
    style.insertRule('p { margin: 0; }', 0); 
else if ('addRule' in style) 
    style.addRule('p', 'margin: 0', 0); 
3

Questo è stato testato per funzionare su tutti i principali browser (Chrome/Safari/FF/Opera/IE) tra cui IE6,7 +8:

function createCSS(css, doc) { 
    doc = doc || document; 
    var style = doc.createElement("style"); 
    style.type = "text/css"; 

    if (!window.opera && 'styleSheet' in style && 'cssText' in style.styleSheet) { 
     // Internet Explorer 6-8 don't support adding text nodes to 
     // styles, so use the proprietary `styleSheet.cssText` instead 
     style.styleSheet.cssText = css; 
    } 
    else { 
     // Otherwise use the standard method 
     style.appendChild(doc.createTextNode(css)); 
    } 

    // Note the `|| document.body` as getting the 
    // head doesn't always work on e.g. Safari 1.0 
    var head = doc.getElementsByTagName("head")[0] || doc.body; 

    // Add the new style of higher priority than the last 
    // ones if there's already other elements in the head 
    if (head.firstChild) { 
     head.insertBefore(style, head.firstChild); 
    } 
    else { 
     head.appendChild(style); 
    } 
} 

Poiché tale codice è scritto, è relativo al documento di essere servito in modo potrebbe essere necessario essere modificato per renderlo relativo ad un altro percorso, oppure è possibile utilizzare percorsi delle immagini assoluti nel CSS.

EDIT: rimosso tutti i riferimenti innerHTML a favore di utilizzare il più standard createTextNode quando possibile e ripulito diverse cose.

+0

Questa sembra una risposta molto legittima, non che le altre risposte non siano poi così male. andando a fare qualche test prima, prima di sceglierlo come risposta accettata. GRAZIE molto, se funziona. – GlassGhost

+0

Non c'è bisogno di 'delete _CSS'. Non causerà un errore, ma non fa nulla poiché solo le proprietà degli oggetti possono essere cancellate. –

+0

È necessario sostituire il div con uno span per evitare di creare una nuova riga. – xavierm02

2

So che questo è un thread vecchio, ma stavo cercando una soluzione per inserire stili CSS dinamicamente che funzioni con tutti i principali/principali browser. Voglio condividere la mia soluzione con te. La soluzione di David non funziona bene (mi dispiace). Ho creato una classe javascript/jQuery tooltip che può funzionare con stili in linea, ma può anche funzionare con stili con stili CSS. (offtopic: anche la classe può allineare automaticamente i tooltip come i tooltip predefiniti).

Forse ti chiedi quali sono i vantaggi quando inserisci CSS come nell'esempio sopra. Bene, non hai bisogno di un file CSS aggiuntivo con gli stili e puoi aggiungere dinamicamente degli stili dallo script e quando lavori con le immagini puoi cambiare dinamicamente il percorso delle immagini se vuoi (quindi non devi cambiare file). Inoltre è possibile inserire gli stili SOPRA altri fogli di stile/regole di stile e le regole di stile applicate possono essere modificate negli altri fogli di stile seguenti (ciò non è possibile quando si utilizzano stili in linea o quando si inseriscono le regole inserite SOTTO qualsiasi foglio di stile esistente).

Questa funzione funziona con Opera/Firefox/IE7/IE8/IE9/Chrome/Safari (senza alcuna modifica applicata!):

function addHtmlStyles(sCss, oBefore) 
    { 
    var oHead = document.getElementsByTagName('head')[0]; 
    if(!oHead || oHead == null) 
     { return false; } 

    var bResult = false, 
     oStyle = document.createElement('style'); 
    oStyle.type = 'text/css'; 
    oStyle.rel = 'stylesheet'; 
    oStyle.media = 'screen'; 

    if(typeof oStyle.styleSheet == 'object') 
     { // IE route (and opera) 
     try{ oStyle.styleSheet.cssText = sCss; bResult = true; } 
     catch(e) {} 
     } 
    else { 
      // Mozilla route 
      try{ oStyle.innerHTML = sCss; bResult = true; } 
      catch(e) {}; 
      if(!bResult) 
      { 
       // Webkit route 
       try{ oStyle.innerText = sCss; bResult = true; } 
       catch(e) {}; 
      } 
      } 

    if(bResult) 
    { 
     try 
     { 
     if(typeof oBefore == 'object') 
     { oHead.insertBefore(oStyle, oBefore); } 
     else { oHead.appendChild(oStyle); } 
     } 
     catch(e) { bResult = false; } 
    } 

return bResult; 
} 

Si restituisce true quando ok o falsa quando fallire. Ad esempio:

var sCss = '#tooltip {background:"#FF0000";}'; 

// get first stylesheet with jQuery, we don't use $('head') because it not always working 
// If there is no stylesheet available, it will be added at the end of the head tag. 
var oHead = $(document.getElementsByTagName('head')[0]), 
    oFirst = oHead.find('[rel=stylesheet]').get(0); 

if(addHtmlStyles(sCss, oFirst)) 
{ alert('OK'); } 
else { alert('NOT OK'); } 

Questo è tutto. Spero ti piaccia la soluzione. Greetz, Erwin Haantjes

+0

Non riuscivo a farlo funzionare con la risposta vista, tuttavia l'ho ottenuto a metà lavorando unendo il mio codice originale e il tuo in una nuova funzione, sicuramente lavorando in firefox e principalmente lavorando in chrome. – GlassGhost

+0

Strano che non funzioni affatto in Chrome ora forse si è aggiornato da solo o qualcosa del genere. – GlassGhost

+0

Bene, quando l'ho provato; non ha funzionato con Chrome o Internet Explorer. Inoltre ho aggiunto la correzione per la testa al codice fornito che ora funziona con tutto tranne IE8 e precedenti ed è più conciso del codice. scusa ho dimenticato di svenderlo. Inoltre è passato un po 'di tempo da quando ho testato il tuo codice che potrebbe funzionare ora con Chrome come stanno continuando ad aggiornare. Al ritmo attuale la metà della taglia sembra che andrà alla persona con 3 upvotes, dato che non riesco a ottenere alcun codice ricevuto su questa pagina per funzionare con IE8 e precedenti. Sto lasciando questo senza risposta, a meno che IE7 (e si spera IE6) possa essere fatto funzionare. – GlassGhost

1

@GlassGost: Weird non funziona per te perché lo collaudo in diversi browser (anche su quelli mobili). Forse è utile aggiungere css quando il DOM è pronto:

$(document).ready(function() 
{ 
    ....... 
}); 

Inoltre volte aiuta a cambiare l'ordine degli script di caricamento.

Greetz, Erwin Haantjes

+0

Che cosa testate precisamente? Anche nel mio caso; uno stile wikipedia, non riesco ad accedere quando lo script è caricato o l'ordine di caricamento degli script. – GlassGhost

+0

Testare la funzione 'addHtmlStyles' in diversi browser. Non capisco la tua domanda. Uno stile di wikipedia? accesso?Greetz Erwin Haantjes – Codebeat

0

Questo funziona bene per me su tutti i browser attuali con qualsiasi tipo di documento (che presumo si deve avere a che fare con più documenti, o altrimenti non avrebbe un parametro Doc) :

function add_css_style(css_rules, document) { 
    document = document || self.document; 
    var style = document.createElementNS("http://www.w3.org/1999/xhtml", "style"); 
    style.type = "text/css"; 
    style.appendChild(document.createTextNode(css_rules)); 
    document.documentElement.appendChild(style); 
} 

Se si desidera utilizzare il CSSOM invece:

function add_css_style(css_rules, document) { 
    document = document || self.document; 
    var stylesheet = document.documentElement.appendChild(
     this.createElementNS("http://www.w3.org/1999/xhtml", "style") 
    ).sheet; 
    stylesheet.insertRule("@media all{" + rules + "}", 0); 
} 
+0

Non funziona per me con IE8 (IE7, IE6 non ho controllato ma non mi aspetto nulla) – GlassGhost

+0

Ho detto corrente. IE9 è l'attuale IE. –

Problemi correlati