2009-02-22 24 views
230

¿Es posible importar hojas de estilo CSS en una página html usando Javascript? Si es así, ¿cómo se puede hacer esto?Cómo cargar archivos CSS usando Javascript?

PD el javascript se alojará en mi sitio, pero quiero que los usuarios puedan poner la etiqueta <head> de su sitio web, y debería poder importar un archivo css alojado en mi servidor en la página web actual . (Tanto el archivo css como el archivo javascript se alojarán en mi servidor).

+0

También se pregunta sobre jQuery http://stackoverflow.com/questions/2685614/load-external-css-file-like -scripts-in-jquery-which-is-compatible-in-ie-also – jcubic

Respuesta

319

Esta es la forma de hacerlo de la "vieja escuela", que con suerte funciona en todos los navegadores. En teoría, usaría setAttribute desafortunadamente IE6 no lo admite consistentemente.

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); 
} 

Este ejemplo comprueba si el CSS ya se ha agregado, por lo que solo lo agrega una vez.

Ponga ese código en un archivo javascript, haga que el usuario final simplemente incluya el javascript, y asegúrese de que la ruta CSS sea absoluta, de modo que se cargue desde sus servidores.

VanillaJS

He aquí un ejemplo que usa llano JavaScript para inyectar un enlace de CSS en el elemento head basado en la parte de nombre de archivo de la 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> 

Introduce el código justo antes del cierre head la etiqueta y el CSS se cargarán antes de que se represente la página. El uso de un archivo JavaScript externo (.js) provocará que aparezca un Flash de contenido sin estilo (FOUC).

+5

¿Qué tal ejecutar una devolución de llamada una vez que el archivo CSS se haya cargado? – jchook

+1

Esto es bastante más complejo de hacer de manera confiable. Las populares bibliotecas Javascript ahora generalmente tienen alguna forma de cargar javascript y hojas de estilo con una devolución de llamada. Como ejemplo, vea [YUI Get] (http://yuilibrary.com/yui/docs/get/). –

+0

Ver [Ext.util.CSS.swapStyleSheet] (http://docs.sencha.com/ext-js/4-1/#!/api/Ext.util.CSS-method-swapStyleSheet) para la biblioteca Ext JS –

45

supongo que algo como esto guión haría:

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

Este JS archivo contiene la siguiente declaración:

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

La dirección del javascript y css tendría que ser absoluta si están para referirse a tu sitio

Muchas técnicas de importación de CSS se discuten en este artículo "Say no to CSS hacks with branching techniques".

Pero el artículo "Using JavaScript to dynamically add Portlet CSS stylesheets" menciona también la posibilidad createStyleSheet (método patentado para 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); 
} 
//]]> 
+0

Esto es lo que se me ocurre para agregar 'document.createStyleSheet()' a los navegadores que no lo tienen: http://stackoverflow.com/questions/524696/how-to-create-a-style-tag-with-javascript/524798 # 524798 – Christoph

+0

Gracias por este comentario – VonC

+1

No estoy seguro exactamente en qué caso, pero en algunos casos, 'document.write' isn ' t recomendado porque se acabó escribe el cuerpo entero de tu sitio web. –

2

El YUI library podría ser lo que están buscando . También es compatible con la carga de dominios cruzados.

Si usa jquery, this plugin hace lo mismo.

3

Hay un plugin jquery general que carga archivos css y JS sincronizados y asych a pedido. También realiza un seguimiento de lo que ya se ha cargado :) véase: http://code.google.com/p/rloader/

7

Sé que esto es un hilo muy antiguo, pero aquí viene mi hijo de 5 centavos.

Hay otra manera de hacer esto dependiendo de cuáles sean sus necesidades.

Tengo un caso en el que quiero que un archivo CSS esté activo solo por un tiempo. Como cambiar css. Activa el CSS y luego después de otro evento desaturalízalo.

En lugar de cargar el CSS de forma dinámica y luego quitarlo, puede agregar un ID de clase/una delante de todos los elementos en el nuevo CSS y luego simplemente cambiar esa clase/ID del nodo base de su CSS)

Con esta solución, tendrá más archivos CSS inicialmente cargados pero tendrá una forma más dinámica de cambiar los diseños CSS.

13

Llame a la siguiente función para cargar dinámicamente archivos CSS o 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) 
} 

Pase la ruta completa del archivo con el nombre filename argumento.

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

Estoy usando thymeleaf y esto funciona bien. Gracias

3

Aquí está una manera con el método de creación de elemento de jQuery (mi preferencia) y con devolución de llamada 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); 
42

Si utiliza jQuery:

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

Por debajo de un código completo el uso de JS carga y/o 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']))(); 
5

Si quieres saber (o esperar) hasta el estilo itse Si ha cargado funciona esto:

// 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); 
    }); 
}; 
+0

cómo lo uso –

1

Usar este código:

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); 
Cuestiones relacionadas