web-dev-qa-db-fra.com

Injecter la feuille de style CSS sous forme de chaîne à l'aide de Javascript

Je développe une Chrome, et j'aimerais que les utilisateurs puissent ajouter leurs propres styles CSS pour changer l'apparence des pages de l'extension (pas des pages Web). J'ai regardé en utilisant document.stylesheets, mais il semble qu'il souhaite que les règles soient divisées et ne vous laisse pas injecter une feuille de style complète. Existe-t-il une solution qui me permettrait d'utiliser une chaîne pour créer une nouvelle feuille de style sur une page?

Je n'utilise actuellement pas jQuery ou similaire, donc des solutions Javascript pures seraient préférables.

31
Dan Hlavenka

Vous pouvez créer un élément de style et ajouter la chaîne en tant que innerHTML. Quelque chose comme ça:

function addStyleString(str) {
    var node = document.createElement('style');
    node.innerHTML = str;
    document.body.appendChild(node);
}

addStyleString('body { color: red }');
addStyleString('body { background: silver }');
// This way allows you to add CSS in multiple passes

( Édition importante: Sachez que IE9 et ci-dessous n'autorise que jusqu'à 32 feuilles de style , alors faites attention quand en utilisant l'extrait ci-dessus. Le nombre a été augmenté à 4095 dans IE10.)

Si, lorsqu'un utilisateur ajoute un nouveau CSS, vous souhaitez supprimer les anciens styles et ajouter le nouveau, vous pouvez changer la fonction pour avoir une référence à un nœud.

(function() {
    var node = document.createElement('style');
    document.body.appendChild(node);
    window.addStyleString = function(str) {
        node.innerHTML = str;
    }
}());

addStyleString('body { color: red }');
addStyleString('body { background: silver }');
// This way will remove the old style when the new one is added
61
Liam Newmarch

Grâce à ce type , j'ai pu trouver la bonne réponse. Voici comment procéder:

function addCss(rule) {
  let css = document.createElement('style');
  css.type = 'text/css';
  if (css.styleSheet) css.styleSheet.cssText = rule; // Support for IE
  else css.appendChild(document.createTextNode(rule)); // Support for the rest
  document.getElementsByTagName("head")[0].appendChild(css);
}

// CSS rules
let rule  = '.red {background-color: red}';
    rule += '.blue {background-color: blue}';

// Load the rules and execute after the DOM loads
window.onload = function() {addCss(rule)};

violon

16
John R Perry

J'ai eu ce même besoin récemment et j'ai écrit une fonction pour faire la même chose que celle de Liam, sauf pour permettre également plusieurs lignes de CSS.

injectCSS(function(){/*
    .ui-button {
        border: 3px solid #0f0;
        font-weight: bold;
        color: #f00;
    }
    .ui-panel {
        border: 1px solid #0f0;
        background-color: #eee;
        margin: 1em;
    }
*/});

// or the following for one line

injectCSS('.case2 { border: 3px solid #00f; } ');

Le source de cette fonction . Vous pouvez télécharger à partir du Repo Github . Ou voyez plus exemple d'utilisation ici .

Ma préférence est de l'utiliser avec RequireJS , mais cela fonctionnera également comme une fonction globale en l'absence d'un chargeur AMD.

3
Pat Cullen