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).
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.
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.
Si vous utilisez jquery:
$('head').append('<link rel="stylesheet" type="text/css" href="style.css">');
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);
}
//]]>
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
.
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\" />");
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.
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);
});
};
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:
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);
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/
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);
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.
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'])) ();
Vous pouvez utiliser pour cela bibliothèque YUI ou utiliser ceci article à implémenter
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