Javascript kullanarak CSS dosyaları nasıl yüklenir?


316

Javascript kullanarak css stil sayfalarını bir html sayfasına aktarmak mümkün müdür? Öyleyse, nasıl yapılabilir?

PS javascript sitemde barındırılacak, ancak kullanıcıların <head>web sitelerinin etiketini koymak istiyorum ve sunucumda barındırılan bir css dosyasını geçerli web sayfasına aktarabilmelidir. (hem css dosyası hem de javascript dosyası sunucumda barındırılacaktır).


Yanıtlar:


416

İşte umarım tüm tarayıcılarda çalışan "eski okul" yolu. Teorik olarak, setAttributene yazık ki IE6 tutarlı bir şekilde desteklemez kullanırsınız .

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

Bu örnek, CSS'nin önceden eklenmiş olup olmadığını kontrol eder, böylece yalnızca bir kez ekler.

Bu kodu bir javascript dosyasına koyun, son kullanıcının basitçe javascript eklemesini sağlayın ve CSS yolunun mutlak olduğundan emin olun, böylece sunucularınızdan yüklenir.

VanillaJS

headURL'nin dosya adı bölümüne göre öğeye bir CSS bağlantısı enjekte etmek için düz JavaScript kullanan bir örnek :

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

Kodu kapanış headetiketinden hemen önce ekleyin; sayfa oluşturulmadan önce CSS yüklenecektir. Harici bir JavaScript ( .js) dosyası kullanmak , stilsiz içerik ( FOUC ) içeren bir Flash'ın görünmesine neden olur.


6
CSS dosyası yüklendikten sonra geri arama yapmaya ne dersiniz?
jchook

1
Güvenilir bir şekilde yapmak oldukça karmaşıktır. Popüler Javascript kitaplıkları artık genellikle bir geri çağrı ile bir tür javascript ve stil sayfası yükleme şekline sahiptir. Örnek olarak, bkz. YUI Get .


2
@jonnybojangles jQuery.noConflict kullanmak, jQuery ile ilgili tüm referanslarınızı $ olarak yeniden adlandırmak anlamına gelir. CSS yükleyicisi için farklı bir değişken adı kullanmak çok daha kolay olurdu.
tommypyatt

2
@jchook Eklemeden link.onload = function(){ ... }önce ekleyerek bir geri arama
ekledim

74

Jquery kullanıyorsanız:

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

1
bu sadece stil sayfası sayfa yükleme hakkından önce enjekte edilirse işe yarar mı? Bu komutu, dropbox'ta barındırdığım bir css dosyası ile yüklü bir sayfada konsolun içinde çalıştırdığımda işe yaramaz. Nasıl bu işi yapabilirim herhangi bir fikir:$('head').append('<link rel="stylesheet" type="text/css" href="https://dl.dropboxusercontent.com/s/ep1nzckmvgjq7jr/remove_transitions_from_page.css">');
thomas

50

Sanırım bu senaryo gibi bir şey yapardı:

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

Bu JS dosyası aşağıdaki ifadeyi içerir:

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

Sitenize atıfta bulunacaksa, javascript ve css adreslerinin mutlak olması gerekir.

Birçok "CSS içe aktarma tekniği " bu dallanma tekniklerine sahip CSS saldırılarına hayır deyin " makalesinde ele alınmıştır.

Ancak "Portlet CSS stil sayfalarını dinamik olarak eklemek için JavaScript kullanma" makalesinde ayrıca CreateStyleSheet olasılığı da (IE için özel yöntem) belirtilmektedir:

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

İşte document.createStyleSheet()sahip olmayan tarayıcılara eklemek için geldim : stackoverflow.com/questions/524696/…
Christoph

1
Tam olarak hangi durumda olduğundan emin değilim, ancak bazı durumlarda document.writeweb sitenizin tüm gövdesinin üzerine yazdığı için önerilmez.
Eduard Luca

@VonC, üzerinden <style>ilk çocuk olduğunu varsaymak yerine öğeyi doğrudan almak için bir işlevi var mı ? <head>("head")[0]
Pacerier

@Pacerier Bunu groups.google.com/forum/#!topic/prototype-scriptaculous/… ' da tartıştığınızı bulacağınıza inanıyorum . Örneğin:var style = document.getElementsByTagName("style")[0];
VonC

20

Element.insertAdjacentHTML çok iyi tarayıcı desteğine sahiptir ve bir satıra bir stil sayfası ekleyebilir.

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

12

Tarzın kendisi yüklenene kadar bilmek (veya beklemek) istiyorsanız bu çalışır:

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

bunu nasıl kullanırım
Raj Sharma

Sen fetchStyle (url) .then (function () {stuff here}) vaatleri okumak
Ben Taliadoros

8

Bu oldukça eski bir iplik olduğunu biliyorum ama işte benim 5 sent geliyor.

İhtiyaçlarınızın ne olduğuna bağlı olarak bunu yapmanın başka bir yolu var.

Ben sadece bir süre aktif olmasını istiyorum bir css dosyası var. Css değiştirme gibi. Css'yi etkinleştirin ve ardından başka bir olaydan sonra devre dışı bırakın.

Css'i dinamik olarak yüklemek ve ardından kaldırmak yerine, yeni css'deki tüm öğelerin önüne bir Class / id ekleyebilir ve daha sonra css'inizin temel düğümünün (body etiketi gibi) bu sınıfını / kimliğini değiştirebilirsiniz.

Bu çözümle başlangıçta daha fazla css dosyası yüklenir, ancak css mizanpajlarını değiştirmenin daha dinamik bir yolu vardır.


7

Modern bir tarayıcıda böyle kullanabilirsiniz promise. İçinde söz veren bir yükleyici işlevi oluşturun:

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

Açıkçası CSS yüklendikten sonra bir şeylerin yapılmasını istersiniz. CSS aşağıdaki gibi yüklendikten sonra çalışması gereken işlevi çağırabilirsiniz:

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

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

    return DoAfterCSSHasLoaded();
} );

Nasıl çalıştığını derinlemesine anlamak istiyorsanız yararlı bağlantılar:

Vaatlerle ilgili resmi dokümanlar

Vaatler için faydalı rehber

Vaatlerle ilgili harika bir tanıtım videosu


6

Bu kodu kullanın:

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


4

İşte jQuery öğesi oluşturma yöntemi (benim tercihim) ve geri arama ile bir yol 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);



2

JS ve / veya CSS yüklemek için kullanılan tam kodun altında

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

Sadece css değil tüm varlıkları (js, css, resimler) yüklemek ve bir sürü dosya için onload olayını işlemek için bir yol daha paylaşmak istiyorum . Öyle async-assets-loader. Aşağıdaki örneğe bakın:

<script src="https://unpkg.com/async-assets-loader"></script>
<script>
var jsfile = "https://code.jquery.com/jquery-3.4.1.min.js";
var cssfile = "https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css";
var imgfile = "https://logos.keycdn.com/keycdn-logo-black.png";
var assetsLoader = new asyncAssetsLoader();
assetsLoader.load([
      {uri: jsfile, type: "script"},
      {uri: cssfile, type: "style"},
      {uri: imgfile, type: "img"}
    ], function () {
      console.log("Assets are loaded");
      console.log("Img width: " + assetsLoader.getLoadedTags()[imgfile].width);
    });
</script> 

Göre uyumsuz-varlıklar-yükleyici docs


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

Kekik kullanıyorum ve bu iyi çalışıyor. Teşekkürler


th:hrefİstemci tarafında özellik eklemenin anlamı nedir ? Thymeleaf tarafından işlenmeyecek, bu yüzden burada gereksiz görünüyor.
Slava Semushin
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.