web-dev-qa-db-ja.com

CSSファイルが完全にロードされたことを検出する方法はありますか?

<script>タグと<link>タグを挿入してファイルをロードするJavaScriptとCSSのレイジーローダーをたくさんテストしてきました。ただし、問題は、<link>タグがonloadを起動しないため、いつロードされたかを検出するのが難しいことです。これについて私が見つけた唯一の回避策は、ダミー要素にdisplay: none;(ロードされるCSSファイル内)を設定し、その要素をポーリングして、表示するように設定されているかどうかを確認することです:なし。しかし、それは醜いことは別として、もちろん単一のCSSファイルに対してのみ機能します。

だから私は疑問に思っていました。 CSSファイルがロードされているかどうかを検出する他の方法はありますか?

31
Lukas

編集:ブラウザがオンロードイベントをサポートしていることに注意してくださいCSSファイルは私の最初の答えから改善されました。ただし、完全にはサポートされていないため、以下の私の回答にはまだある程度の関連性があります。 互換性チャートはこちら 、ソースがどれほど正当かわからない。

さて、私はついに解決策を見つけました。

この男 http://tugll.tugraz.at/96784/weblog/9080.html リンクタグを挿入し、document.styleSheets [index] .rulesをポーリングして、未定義でなくなるまで(コースは新しく挿入されたファイルのインデックスです)。残念ながら、彼のコードはバグがあり、SafariとFFでのみ機能します。そこで、バグを修正し、OperaとInternetExplorerの機能を追加し、複数のCSSファイルとJSファイルを追加する機能と1つの最終コールバック(すべてのファイルがロードされたとき)を甘くてシンプルなレイジーローダーに追加しました-関数。結果はここにあります:

https://github.com/LukasBombach/Lazyloader

16
Lukas

ファイルの最後に特定のCSSルールを追加して、CSSが適用されるのを待ちます(JavaScriptで確認してください)。その後、CSSがロードされたことを確認できます。しかし、私はそれについての経験がありません。簡単なアイデアだけでも試してみる価値があるかもしれません。

3
Daniel Böhmer

編集:(WebKitをサポートしていない可能性があるため)

だから私はむしろお勧めします JQuery LOADER

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

LazyLoad JavaScriptライブラリをご覧ください。

LazyLoadは、小さな(最小化された1,541バイトのみ)依存関係のないJavaScriptライブラリであり、外部JavaScriptおよび(このバージョンの新機能)CSSファイルをオンデマンドで非常に簡単にロードできます。これは、ページの残りの部分の読み込みが完了した後、または必要に応じてオンデマンドで、大きな外部スクリプトやスタイルシートをすばやく目立たないように読み込むのに理想的です。

このバージョンのLazyLoadは、CSSのサポートに加えて、それをサポートするブラウザーでの複数のリソースの並列ロードのサポートも追加します。複数のリソースを並行してロードするには、単一のLazyLoadcalでURLの配列を渡すだけです。

3
sv88erik

何が変わったのかについての洞察を提供したいと思いました。

Mozillaの<link>のドキュメントの最後の段落の1つによると、ロードイベントはFFバージョン9以降およびChrome 19以降)のリンク要素にアタッチできます。 IEおよびSafariは記載されていません。 https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link

2
Steven Nelson

now現在のバージョンのChromeおよびFirefoxは、リンクでonloadイベントを発生させることを知っておく価値があります。

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

Supplyのようなスクリプトローダーを使用すると、次のようになります。

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

参照: SupplyJS

1
jAndy

「CSSルールのロードチェック」について:

JSスクリプトで、次のような単純なルールを含むスタイルタグを頭に追加した場合:#loadingCss {display:block; }

それよりも、すべてのCSSファイルに次のようなものを追加する必要があります。#loadingCss {display:none; }

ドキュメントの先頭で、リンクタグの前にスタイルタグを追加します。このように、CSSファイルのCSSルールがより重要になります(同じセレクター->同じ優先度、ドキュメントの最後のものが勝者です)。

それよりも、JSスクリプトでは、#loadingCssの可視性を確認するだけです。 CSSファイルがロードされていることがわかったら、スタイルタグを削除できます。

次にロードするCSSファイルについて、head要素の最後にこのスタイルタグを再度追加できます。

このように、1つのルールだけで、すべてのCSSファイルのロードを管理できます。このソリューションの唯一の問題:一度に複数のCSSファイルをロードすることはできません。しかし、そうする方法を見つけることは可能だと確信しています。

しかしとにかく、このソリューション(CSSルールを使用して読み込みをチェックする)が非常に優れたソリューションであるかどうかはわかりません。多分これを行う他の方法があります。

1
Nicolas

これを試してください:1-頭にcssをプリロードします

<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-フッターにjsファイルをプリロードします

    <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-タグの前</body> 追加

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

Firefox 57、chrome 61、yandex、opera、ie

1
Hung Pham

これは私がこれまでに見つけた最も単純で最良の解決策であり、完全に機能します。

var head = document.getElementsByTagName('head')[0];
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = css_url;

head.appendChild(link);

var img = document.createElement('img');
document.body.appendChild(img);

img.onerror = img.onload = function() {
    img.onerror = img.onload = null;
    document.body.removeChild(img);
    // do whatever you need to do when css loaded;
};

img.src = css_url;
0
Frane Poljak