web-dev-qa-db-fra.com

Ajouter CSS à <head> avec JavaScript?

Est-il possible d’ajouter des css d’une chaîne du fichier javascript à la tête d’un document javascript?

Disons que nous avons une page Web, qui a un script lightbox, ce script nécessite un fichier CSS pour fonctionner. 

En ajoutant maintenant ce fichier css avec <link>, le téléchargement du fichier css sera fait même pour les personnes pour lesquelles js n'est pas activé. 

Je sais que je peux charger dynamiquement le fichier css avec le script, mais cela signifie également qu'il y aura 2 requêtes http, et dans les cas où il n'y a que peu ou pas de fichiers css dans le fichier, je trouve cela inefficace. 

Alors je me suis dit que si vous pouviez mettre le css que vous avez dans le fichier css, dans le script, faire analyser le css par le script et l’ajouter dans la tête, ou encore mieux, le faire ajouter le css directement dans le <head> du document. 

Mais je n'ai rien trouvé en ligne qui suggère que c'est possible, alors est-il possible d'ajouter CSS à la tête avec js?

Edit + SOLUTION:

J'ai édité la réponse de roryf pour travailler avec plusieurs navigateurs (sauf IE5)

Javascript:

 function addcss(css){
    var head = document.getElementsByTagName('head')[0];
    var s = document.createElement('style');
    s.setAttribute('type', 'text/css');
    if (s.styleSheet) {   // IE
        s.styleSheet.cssText = css;
    } else {                // the world
        s.appendChild(document.createTextNode(css));
    }
    head.appendChild(s);
 }
56
Timo Huovinen

Pendant que vous essayez d’ajouter une chaîne CSS à <head> avec JavaScript? En injectant une chaîne de CSS dans une page, il est plus facile de faire cela avec l'élément <link> que l'élément <style>.

Ce qui suit ajoute la règle p { color: green; } à la page.

<link rel="stylesheet" type="text/css" href="data:text/css;charset=UTF-8,p%20%7B%20color%3A%20green%3B%20%7D" />

Vous pouvez créer ceci en JavaScript simplement en encodant votre chaîne de code CSS par l'URL et en lui ajoutant l'attribut HREF. Beaucoup plus simple que toutes les bizarreries d’éléments <style> ou d’accès direct aux feuilles de style.

var linkElement = this.document.createElement('link');
linkElement.setAttribute('rel', 'stylesheet');
linkElement.setAttribute('type', 'text/css');
linkElement.setAttribute('href', 'data:text/css;charset=UTF-8,' + encodeURIComponent(myStringOfstyles));

Cela fonctionnera à partir de IE 5.5

La solution que vous avez marquée fonctionnera, mais cette solution nécessite moins d’opérations dom et un seul élément.

17
moefinley

Si vous ne voulez pas vous fier à une bibliothèque javascript, vous pouvez utiliser document.write() pour cracher le css requis, encapsulé dans des balises style, directement dans le document head:

<head>
  <script type="text/javascript">
    document.write("<style>body { background-color:#000 }</style>");
  </script>
  # other stuff..
</head>

De cette façon, vous évitez de lancer une requête HTTP supplémentaire.

Il y a d'autres solutions qui ont été suggérées/ajoutées/supprimées, mais je ne vois pas l'intérêt de trop compliquer quelque chose qui fonctionne déjà bien entre navigateurs. Bonne chance!

http://jsbin.com/oqede3/edit

24
Jeriko

Edit: Comme le suggère Atspulgs, vous pouvez obtenir le même résultat sans jQuery à l’aide de querySelector :

document.querySelector('head').innerHTML += '<link rel="stylesheet" href="styles.css" type="text/css"/>';

Réponse plus ancienne ci-dessous.


Vous pouvez utiliser la bibliothèque jQuery pour sélectionner votre élément head et y ajouter du code HTML, de la manière suivante:

$('head').append('<link rel="stylesheet" href="style2.css" type="text/css" />');

Vous pouvez trouver un tutoriel complet pour résoudre ce problème ici

24
thomaux

Une solution simple, non jQuery, mais avec un peu de bidouille pour IE:

var css = ".lightbox { width: 400px; height: 400px; border: 1px solid #333}";

var htmlDiv = document.createElement('div');
htmlDiv.innerHTML = '<p>foo</p><style>' + css + '</style>';
document.getElementsByTagName('head')[0].appendChild(htmlDiv.childNodes[1]);

Il semble que IE n'autorise pas la définition de innerText, innerHTML ou l'utilisation de appendChild sur des éléments style. Voici un rapport de bogue qui le démontre, bien que je pense qu’il identifie le problème de façon incorrecte. La solution de contournement ci-dessus est tirée des commentaires sur le rapport de bogue et a été testée dans IE6 et IE9.

Que vous utilisiez cette solution, document.write ou une solution plus complexe dépendra vraiment de votre situation.

14
roryf

Voici une fonction qui créera dynamiquement une règle CSS dans tous les principaux navigateurs. createCssRule prend un sélecteur (par exemple "p.purpleText"), une règle (par exemple "couleur: violet;") et éventuellement une Document (le document actuel est utilisé par défaut):

var addRule;

if (typeof document.styleSheets != "undefined" && document.styleSheets) {
    addRule = function(selector, rule) {
        var styleSheets = document.styleSheets, styleSheet;
        if (styleSheets && styleSheets.length) {
            styleSheet = styleSheets[styleSheets.length - 1];
            if (styleSheet.addRule) {
                styleSheet.addRule(selector, rule)
            } else if (typeof styleSheet.cssText == "string") {
                styleSheet.cssText = selector + " {" + rule + "}";
            } else if (styleSheet.insertRule && styleSheet.cssRules) {
                styleSheet.insertRule(selector + " {" + rule + "}", styleSheet.cssRules.length);
            }
        }
    }
} else {
    addRule = function(selector, rule, el, doc) {
        el.appendChild(doc.createTextNode(selector + " {" + rule + "}"));
    };
}

function createCssRule(selector, rule, doc) {
    doc = doc || document;
    var head = doc.getElementsByTagName("head")[0];
    if (head && addRule) {
        var styleEl = doc.createElement("style");
        styleEl.type = "text/css";
        styleEl.media = "screen";
        head.appendChild(styleEl);
        addRule(selector, rule, styleEl, doc);
        styleEl = null;
    }
};

createCssRule("body", "background-color: purple;");
9
Tim Down

Voici un moyen simple.

/**
 * Add css to the document
 * @param {string} css
 */
function addCssToDocument(css){
  var style = document.createElement('style')
  style.innerText = css
  document.head.appendChild(style)
}
0
Ally