2009-02-22 17 views
230

Czy można zaimportować arkusze stylów CSS na stronę html przy użyciu Javascript? Jeśli tak, jak można to zrobić?Jak załadować pliki CSS przy użyciu Javascript?

PS javascript będzie hostowany na mojej stronie, ale chcę, aby użytkownicy mogli umieszczać w swojej witrynie znacznik <head> i powinien być w stanie zaimportować plik css hostowany na moim serwerze do bieżącej strony internetowej . (zarówno plik css, jak i javascript będą przechowywane na moim serwerze).

+0

Istnieje również pytanie o jQuery http://stackoverflow.com/questions/2685614/load-external-css-file-like -scripts-in-jquery-which-is-compatible-in-ie-also – jcubic

Odpowiedz

319

Oto sposób "starej szkoły", który, mam nadzieję, działa we wszystkich przeglądarkach. Teoretycznie użyłbyś setAttribute, niestety IE6 nie obsługuje tego konsekwentnie.

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

Ten przykład sprawdza, czy CSS został już dodany, więc dodaje go tylko raz.

Umieść ten kod w pliku javascript, niech użytkownik końcowy po prostu umieści javascript i upewnij się, że ścieżka CSS jest absolutna, więc jest ładowana z twoich serwerów.

VanillaJS

Oto przykład, który używa zwykłego JavaScript wstrzyknąć link CSS do elementu head opartą na części nazwy pliku adresu 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> 

Wstawianie kodu tuż przed zamknięciem head tag i CSS zostaną wczytane przed renderowaniem strony. Użycie zewnętrznego pliku JavaScript (.js) spowoduje pojawienie się Flasha niezaszyfrowanych treści (FOUC).

+5

A co z uruchomieniem wywołania zwrotnego po wczytaniu pliku CSS? – jchook

+1

Jest to bardziej skomplikowane do wykonania niezawodnie. Popularne biblioteki JavaScript mają teraz zazwyczaj pewną formę ładowania javascript i arkuszy stylów z funkcją zwrotną. Jako przykład patrz [YUI Get] (http://yuilibrary.com/yui/docs/get/). –

+0

Zobacz [Ext.util.CSS.swapStyleSheet] (http://docs.sencha.com/ext-js/4-1/#!/api/Ext.util.CSS-method-swapStyleSheet) dla biblioteki Ext JS –

45

Chyba coś takiego scenariusza byłoby zrobić:

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

Ten JS plik zawiera następujące oświadczenie:

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

Adres javascript i css musiałyby być absolutna, jeżeli są one aby odnieść się do Twojej witryny.

Wiele technik importowania CSS omówiono w tym artykule: "Say no to CSS hacks with branching techniques".

Ale artykuł "Using JavaScript to dynamically add Portlet CSS stylesheets" wspomina również możliwość CreateStyleSheet (zastrzeżona metoda dla 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

Oto co wymyśliłem, aby dodać 'document.createStyleSheet()' do przeglądarek, które go nie mają: http://stackoverflow.com/questions/524696/how-to-create-a-style-tag-with-javascript/524798 # 524798 – Christoph

+0

Dziękuję za tę opinię – VonC

+1

Nie jestem pewien, w jakim przypadku, ale w niektórych przypadkach 'document.write' isn ' t zalecane, ponieważ się skończyło zapisuje całą treść Twojej witryny. –

2

YUI library może być to, czego szukasz . Obsługuje również ładowanie między domenami.

Jeśli używasz jquery, this plugin robi to samo.

3

Istnieje ogólna wtyczka jQuery ładująca pliki CSS i JS zsynchronizowane i asych na żądanie. Śledzi również to, co jest już załadowane :) zobacz: http://code.google.com/p/rloader/

7

Wiem, że to całkiem stara nitka, ale tutaj jest moje 5 centów.

Istnieje inny sposób, aby to zrobić w zależności od potrzeb.

Mam przypadek, w którym chcę, aby plik css był aktywny tylko chwilę. Jak przełączanie css. Aktywuj css, a następnie po kolejnym zdarzeniu go deativate.

Zamiast dynamicznie ładować css, a następnie go usunąć, możesz dodać identyfikator Class/an przed wszystkimi elementami w nowym css, a następnie po prostu zmienić klasę/identyfikator węzła podstawowego twojego css (jak tag body).

Będziesz z tym rozwiązaniem mieć więcej załadowanych plików css, ale masz bardziej dynamiczny sposób przełączania układów css.

13

Zadzwoń do następującej funkcji, aby dynamicznie wczytać plik CSS lub 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) 
} 

zdać pełną ścieżkę dostępu do pliku z nazwą jako filename argument.

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

Używam thymeleaf i to działa dobrze. Dzięki

3

Oto sposób metodą tworzenia elementu jQuery (moje preferencje) oraz zwrotnego 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

Jeśli używasz jQuery:

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

Poniżej pełny kod używając do ładowania JS i/lub 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

Jeśli chcesz wiedzieć (lub poczekać), aż styl itse LF został załadowany to działa:

// 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

jak to zrobić? –

1

użyć tego kodu:

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); 
Powiązane problemy