web-dev-qa-db-fra.com

Comment charger des fichiers CSS avec Javascript?

Est-il possible d'importer des feuilles de style CSS dans une page HTML à l'aide de Javascript? Si tel est le cas, comment cela peut-il se faire?

PS le javascript sera hébergé sur mon site, mais je souhaite que les utilisateurs puissent insérer la balise <head> de leur site Web et pouvoir importer un fichier css hébergé sur mon serveur dans la page Web actuelle. . (le fichier css et le fichier javascript seront hébergés sur mon serveur).

284
Click Upvote

Voici la façon de faire "à l'ancienne" qui, espérons-le, fonctionne sur tous les navigateurs. En théorie, vous utiliseriez setAttribute malheureusement, IE6 ne le supporte pas systématiquement.

var cssId = 'myCss';  // you could encode the css path itself to generate id..
if (!document.getElementById(cssId))
{
    var head  = document.getElementsByTagName('head')[0];
    var link  = document.createElement('link');
    link.id   = cssId;
    link.rel  = 'stylesheet';
    link.type = 'text/css';
    link.href = 'http://website.com/css/stylesheet.css';
    link.media = 'all';
    head.appendChild(link);
}

Cet exemple vérifie si le CSS a déjà été ajouté, il ne l'ajoute donc qu'une fois.

Mettez ce code dans un fichier javascript, demandez à l'utilisateur final d'inclure simplement le javascript, et assurez-vous que le chemin d'accès CSS est absolu afin qu'il soit chargé à partir de vos serveurs.

VanillaJS

Voici un exemple qui utilise du code JavaScript simple pour injecter un lien CSS dans l'élément head en fonction de la partie du nom de fichier de l'URL:

<script type="text/javascript">
var file = location.pathname.split( "/" ).pop();

var link = document.createElement( "link" );
link.href = file.substr( 0, file.lastIndexOf( "." ) ) + ".css";
link.type = "text/css";
link.rel = "stylesheet";
link.media = "screen,print";

document.getElementsByTagName( "head" )[0].appendChild( link );
</script>

Insérez le code juste avant la balise de fermeture head et le CSS sera chargé avant le rendu de la page. Si vous utilisez un fichier JavaScript externe (.js), un contenu instantané ( FOUC ) apparaîtra.

383
user58777

Si vous utilisez jquery:

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

Je suppose que quelque chose comme ce script ferait l'affaire:

<script type="text/javascript" src="/js/styles.js"></script>

Ce fichier JS contient l'instruction suivante:

if (!document.getElementById) document.write('<link rel="stylesheet" type="text/css" href="/css/versions4.css">');

Les adresses des scripts javascript et css doivent être absolues si elles doivent faire référence à votre site.

De nombreuses techniques d'importation CSS sont abordées dans cet "Dites non aux hacks CSS utilisant des techniques de création de branches" article.

Mais l'article "Utilisation de JavaScript pour ajouter de manière dynamique des feuilles de style CSS de portlet" mentionne également la possibilité CreateStyleSheet (méthode propriétaire pour IE):

<script type="text/javascript">
//<![CDATA[
if(document.createStyleSheet) {
  document.createStyleSheet('http://server/stylesheet.css');
}
else {
  var styles = "@import url(' http://server/stylesheet.css ');";
  var newSS=document.createElement('link');
  newSS.rel='stylesheet';
  newSS.href='data:text/css,'+escape(styles);
  document.getElementsByTagName("head")[0].appendChild(newSS);
}
//]]>
48
VonC

Appelez la fonction suivante pour charger dynamiquement un fichier CSS ou JavaScript.

function loadjscssfile(filename, filetype) {
  if (filetype == "js") { //if filename is a external JavaScript file
    // alert('called');
    var fileref = document.createElement('script')
    fileref.setAttribute("type", "text/javascript")
    fileref.setAttribute("src", filename)
    alert('called');
  } else if (filetype == "css") { //if filename is an external CSS file
    var fileref = document.createElement("link")
    fileref.setAttribute("rel", "stylesheet")
    fileref.setAttribute("type", "text/css")
    fileref.setAttribute("href", filename)
  }
  if (typeof fileref != "undefined")
    document.getElementsByTagName("head")[0].appendChild(fileref)
}

Transmettez le chemin d'accès complet au fichier avec comme nom l'argument filename.

15
Talha

Element.insertAdjacentHTML supporte très bien le navigateur et peut ajouter une feuille de style sur une ligne.

document.getElementsByTagName("head")[0].insertAdjacentHTML(
    "beforeend",
    "<link rel=\"stylesheet\" href=\"path/to/style.css\" />");
8
dangowans

Je sais que c'est un très vieux fil, mais voici mes 5 centimes.

Il existe une autre façon de procéder, selon vos besoins.

J'ai un cas où je veux qu'un fichier css ne soit actif que pendant un certain temps. Comme css commutation. Activez le css puis, après un autre événement, désactivez-le.

Au lieu de charger le fichier css de manière dynamique, puis de le supprimer, vous pouvez ajouter une classe/un identifiant devant tous les éléments du nouveau fichier css, puis basculer simplement la classe/l'identifiant du nœud de base de votre fichier css (comme une balise body).

Avec cette solution, plus de fichiers css seraient initialement chargés, mais vous disposerez d'un moyen plus dynamique de changer de présentation css.

7
JohanSellberg

Si vous voulez savoir (ou attendre) que le style lui-même ait chargé cela fonctionne:

// this will work in IE 10, 11 and Safari/Chrome/Firefox/Edge
// add ES6 poly-fill for the Promise, if needed (or rewrite to use a callback)

let fetchStyle = function(url) {
  return new Promise((resolve, reject) => {
    let link = document.createElement('link');
    link.type = 'text/css';
    link.rel = 'stylesheet';
    link.onload = function() { resolve(); console.log('style has loaded'); };
    link.href = url;

    let headScript = document.querySelector('script');
    headScript.parentNode.insertBefore(link, headScript);
  });
};
7
sandstrom

Dans un navigateur moderne, vous pouvez utiliser promise comme ceci. Créez une fonction de chargeur contenant une promesse:

function LoadCSS( cssURL ) {

    // 'cssURL' is the stylesheet's URL, i.e. /css/styles.css

    return new Promise( function( resolve, reject ) {

        var link = document.createElement( 'link' );

        link.rel  = 'stylesheet';

        link.href = cssURL;

        document.head.appendChild( link );

        link.onload = function() { 

            resolve(); 

            console.log( 'CSS has loaded!' ); 
        };
    } );
}

Alors évidemment, vous voulez que quelque chose soit fait après le chargement du CSS. Vous pouvez appeler la fonction qui doit être exécutée après le chargement de CSS, comme suit:

LoadCSS( 'css/styles.css' ).then( function() {

    console.log( 'Another function is triggered after CSS had been loaded.' );

    return DoAfterCSSHasLoaded();
} );

Liens utiles si vous souhaitez comprendre en profondeur comment cela fonctionne:

Documents officiels sur promesses

Guide utile des promesses

ne superbe vidéo d'introduction sur les promesses

4
Arthur Tarasov

Utilisez ce code:

var element = document.createElement("link");
element.setAttribute("rel", "stylesheet");
element.setAttribute("type", "text/css");
element.setAttribute("href", "external.css");
document.getElementsByTagName("head")[0].appendChild(element);
3
Gaurav Tripathi

Il existe un plugin général jquery qui charge les fichiers css et JS synchronisés et asych à la demande. Il garde également une trace de ce qui a déjà été chargé :) Voir: http://code.google.com/p/rloader/

3
ez2

Voici un moyen d'utiliser la méthode de création d'éléments de jQuery (ma préférence) et de rappeler onLoad:

var css = $("<link>", {
  "rel" : "stylesheet",
  "type" :  "text/css",
  "href" : "style.css"
})[0];

css.onload = function(){
  console.log("CSS IN IFRAME LOADED");
};

document
  .getElementsByTagName("head")[0]
  .appendChild(css);
3
Lounge9

La bibliothèque YUI est peut-être ce que vous recherchez. Il prend également en charge le chargement entre domaines.

Si vous utilisez jquery, ce plugin fait la même chose.

2
anand.trex

Ci-dessous un code complet utilisé pour charger JS et/ou CSS

function loadScript(directory, files){
  var head = document.getElementsByTagName("head")[0]
  var done = false
  var extension = '.js'
  for (var file of files){ 
    var path = directory + file + extension 
    var script = document.createElement("script")
    script.src = path        
    script.type = "text/javascript"
    script.onload = script.onreadystatechange = function() {
        if ( !done && (!this.readyState ||
            this.readyState == "loaded" || this.readyState == "complete") ) {
            done = true
            script.onload = script.onreadystatechange = null   // cleans up a little memory:
            head.removeChild(script)  // to avoid douple loading
        }
  };
  head.appendChild(script) 
  done = false
 }
}

function loadStyle(directory, files){
  var head = document.getElementsByTagName("head")[0]
  var extension = '.css'
  for (var file of files){ 
   var path = directory + file + extension 
   var link = document.createElement("link")
   link.href = path        
   link.type = "text/css"
   link.rel = "stylesheet" 
   head.appendChild(link) 
 }
}

(() => loadScript('libraries/', ['listen','functions', 'speak', 'commands', 'wsBrowser', 'main'])) ();
(() => loadScript('scripts/', ['index'])) ();

(() => loadStyle('styles/', ['index'])) ();
1
Hasan A Yousef

Vous pouvez utiliser pour cela bibliothèque YUI ou utiliser ceci article à implémenter

1
zihotki
var fileref = document.createElement("link")
fileref.setAttribute("rel", "stylesheet")
fileref.setAttribute("type", "text/css")
fileref.setAttribute("th:href", "@{/filepath}")
fileref.setAttribute("href", "/filepath")

J'utilise thymeleaf et cela fonctionne bien. Merci

0
ekoindra0912