2010-12-20 2 views
30

Ich habe viele Lazy-Loader für JavaScript und CSS getestet, die <Skript> und <Link> Tags zum Laden von Dateien einfügen. Allerdings ist das Problem, dass <link> Tags nicht feuern onload so ist es schwierig zu erkennen, wenn sie geladen sind. Die einzige Problemumgehung, die ich dafür gefunden habe, ist, display: none; (in der CSS-Datei, die geladen werden soll) auf ein dummy-Element zu setzen und dieses Element abzufragen, um zu überprüfen, wann es eingestellt wurde: none. Aber abgesehen davon, dass es hässlich ist, funktioniert das natürlich nur für eine einzige CSS-Datei.Gibt es eine Möglichkeit festzustellen, wenn eine CSS-Datei vollständig geladen wurde?

Also ich frage mich; Gibt es eine andere Möglichkeit festzustellen, ob eine CSS-Datei geladen wurde?

+2

Überprüfen Sie dies: https://github.com/jAndreas/Supply – jAndy

+0

Ich hatte auf eine Nicht-XHR-Lösung gehofft, so dass die Datei ich laden könnte gepuffert und insgesamt * fühlt * sich sauberer an, Dateien hinzuzufügen/zu entfernen, anstatt CSS/JS zu laden und einzufügen/auszuführen ... – Lukas

+0

Es ist die einzige zuverlässige Methode, die mir bekannt ist.Streaming der Daten zum Client und Einfügen in ein "style" -Tag. – jAndy

Antwort

15

bearbeiten: Es sollte beachtet werden, dass die Browser-Unterstützung für Onload-Ereignisse auf CSS-Dateien seit meiner ursprünglichen Antwort verbessert hat. Es wird jedoch nicht vollständig unterstützt, daher hat meine Antwort unten noch einige Relevanz. Here is a compatibility chart, nicht sicher, wie legitim die Quelle ist.

Ok, ich habe endlich eine Lösung gefunden.

Dieser Typ http://tugll.tugraz.at/96784/weblog/9080.html fügt Link-Tags ein und fragt document.styleSheets [index] .rules ab, bis es nicht mehr undefiniert ist (wobei der Index natürlich der Index der neu eingefügten Datei ist). Leider ist sein Code fehlerhaft und funktioniert nur mit Safari & FF. Also habe ich die Fehler behoben, Funktionalität für Opera und Internet Explorer hinzugefügt und sogar Funktionen hinzugefügt, um mehrere CSS- und JS-Dateien hinzuzufügen und einen letzten Callback (wenn alle Dateien geladen sind) in einer süßen und einfachen Lazyloader-Funktion. Das Ergebnis ist hier zu finden:

https://github.com/LukasBombach/Lazyloader

3

Edit: (Wegen der möglichen nicht WebKit unterstützen)

Also würde ich eher empfehlen JQuery LOADER

$("a.button, input.button, button.button").Loader(
{ 
    url: [ 
     'core.css', 
     'theme.css', 
     'button.css' 
    ], 
    success: function() { 
     $(this).button(); 
    } 
}); 

Sie einen Blick auf LazyLoad nehmen können JavaScript-Bibliothek.

LazyLoad ist ein winziges (nur 1541 Bytes minimierte), Abhängigkeit freie JavaScript-Bibliothek, die es super einfach zu laden externe JavaScript und (neu in dieser Version) CSS-Dateien auf Nachfrage macht. Es ist ideal für schnell und unauffällig laden große externe Skripte und Stylesheets entweder träge nach dem Rest der Seite hat fertig geladen oder auf Anfrage als benötigt.

Zusätzlich zur CSS-Unterstützung fügt diese Version von LazyLoad auch die Unterstützung zum parallelen Laden mehrerer Ressourcen in Browsern hinzu, die dies unterstützen. mehr Ressourcen in parallel zu laden, einfach eine Reihe von URLs in einem einzigen LazyLoad passiert cal

+2

Ich würde mich nicht darauf verlassen: '// Gecko und WebKit unterstützen das Onload Event auf Link Nodes nicht, also müssen wir nur nach einer kurzen Verzögerung fertig werden und hoffen auf das Beste. – jAndy

+0

Ich habe Wonkos Lazyload getestet. Es feuert sofort Ihre Onload-Callback-Funktionen (anstatt, wenn das CSS fertig geladen ist), wenn Sie es mit CSS-Dateien verwenden. – Lukas

+0

@jAndy: Ist das ein großes Problem? Es gibt nur eine Zeile, die es ändert;) Wenn Sie jQuery verwenden, kann yue verwenden ..ready() – sv88erik

3

Versuchen Sie, eine bestimmte CSS-Regel an das Ende der Datei hinzufügen und warten, bis die CSS (Kontrolle angewandt werden das über JavaScript). Danach können Sie ziemlich sicher sein, dass das CSS geladen wurde. Ich habe jedoch keine Erfahrung damit. Nur eine schnelle Idee könnte einen Versuch wert sein.

+0

Das Problem damit ist, wenn Sie X CSS-Dateien haben, benötigen Sie X verschiedene CSS-Regeln, und das ist ein Durcheinander. Auch müssen Sie eine Menge von CSS-Datei <-> CSS-Regel-Beziehungen verwalten und Sie können von CSS-Regeln ausgehen. – Lukas

+0

Dem stimme ich zu. Die einfachste Möglichkeit, dies zu implementieren, ist wahrscheinlich das Schreiben einer JS-Funktion zum Laden der CSS-Datei. Wenn die Checker-Regeln nach dem CSS-Dateinamen benannt sind, kann die JS-Funktion die Regel selbst ausarbeiten. Ich habe gerade keine Zeit, dir ein kurzes Beispiel zu geben. –

1

ein Script Loader wie Supply verwenden, würde dies wie folgt aussehen:

supply.listen('text/css', function(payload, filename) { 
    switch(filename) { 
     case: 'foo.css': { 
      // do something 
      break; 
     } 
     case: 'baseball.css': { 
      break; 
     } 
     // ... 
    } 
}); 

supply.files({ 
    stylesheet: [ 
     'foo.css', 
     'baseball.css' 
    ] 
}); 

Ref .: SupplyJS

1

Über die "Last-Überprüfung CSS-Regeln":

Wenn in Ihrem JS Skript, Sie fügen in Ihrem Kopf ein Stil-Tag mit einer einfachen Regel wie: #loadingCss {display: block; }

Dann müssen Sie nur in alle Ihre CSS-Dateien etwas wie hinzufügen: #loadingCss {display: none; }

Im Kopf Ihres Dokuments hängen Sie das Stil-Tag vor dem Link-Tag an. Auf diese Weise wird die CSS-Regel in der CSS-Datei wichtiger (gleicher Selektor -> gleiche Priorität, der letzte im Dokument ist der Gewinner).

Dann, in Ihrem JS-Skript müssen Sie nur # loadingCss Sichtbarkeit überprüfen. Sobald Sie wissen, dass Ihre CSS-Datei geladen ist, können Sie das Stil-Tag entfernen.

Für die nächste CSS-Datei, die Sie laden möchten, können Sie dieses style-Tag am Ende des head-Elements erneut hinzufügen.

Auf diese Weise können Sie mit nur einer Regel alle Ihre CSS-Dateien laden. Das einzige Problem mit dieser Lösung: Sie können nicht mehr als eine CSS-Datei gleichzeitig laden. Aber ich bin mir sicher, dass es möglich ist, einen Weg zu finden.

Aber ich bin mir nicht sicher, dass diese Lösung (mit einer CSS-Regel, um das Laden zu überprüfen) eine sehr gute Lösung ist. Vielleicht gibt es andere Möglichkeiten, dies zu tun.

2

ich einen kleinen Einblick in anbieten wollte, was sich geändert haben.

Laut einem der letzten Abschnitte in Mozillas Dokumentation <link> kann in den FF-Versionen 9 und höher sowie in Chrome 19 und höher ein Load-Ereignis an ein Link-Element angehängt werden. IE und Safari werden nicht angegeben. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link

2

Wissenswertes, dass jetzt aktuelle Versionen von Chrome und Firefox feuern die onload Ereignis auf Links.

var cssFile = document.createElement("link"); 
cssFile.setAttribute("rel", "stylesheet"); 
cssFile.setAttribute("type", "text/css"); 
// Add event listener 
cssFile.onload = function(){ console.log('loaded'); } 
cssFile.setAttribute("href", 'pathToYour.css'); 
document.getElementsByTagName("head")[0].appendChild(cssFile); 
0

versuchen Sie dies: 1- Vorbelastung css auf Kopf

<link rel="preload" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" as="style" onload="this.rel='stylesheet'"> 
<link rel="preload" href="style.css" as="style" onload="this.rel='stylesheet'"> 

2 - Vorbelastung js Datei auf Fußzeile

<link rel="preload" as="script" href="https://ajax.googleapis.com/ajax/libs/jquery/2.2.1/jquery.min.js"> 
    <link rel="preload" as="script" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"> 
    <link rel="preload" as="script" href="script.js"> 

3 - vor Tag </body> hinzufügen

<script>   
/** load defer css - js*/ 
// defer css 
var cssAll = document.querySelectorAll('[as="style"]'); 
for(i = 0; i < cssAll.length; i++){ 
    if(cssAll[i].getAttribute("rel") == "preload"){   
     cssAll[i].setAttribute("rel", "stylesheet"); 
    } 
} 
//defer js 
var jsAll = document.querySelectorAll('[as="script"]'); 
if(!window.jQuery) 
{ 
    // load jquery lib 
    var script = document.createElement('script'); 
    script.type = "text/javascript"; 
    script.src = jsAll[0].getAttribute("href"); 
    document.getElementsByTagName('head')[0].appendChild(script); 
    // load other lib after load jquery 
    script.onload = function() { 
     for(i = 1; i < jsAll.length; i++){ 
      var jsNext = document.createElement('script'); 
      jsNext.type = "text/javascript"; 
      jsNext.src = jsAll[i].getAttribute("href"); 
      document.getElementsByTagName('head')[0].appendChild(jsNext); 
     } 
    } 
} 
</script> 

Ich testete o n Firefox 57, Chrom 61, Yandex, nicht auf Oper getestet und zB

Verwandte Themen