RequireJSを介してCSSをロードする別の方法

再利用可能であると主張するJSモジュールを開発するプロセスでは、多くの場合、jsコードとマークアップに加えてスタイルシートをロードする必要があります。 ご存知のように、スタイル自体は、リンクタグ、スタイルタグ、スタイル属性の3つの方法でドキュメントに追加できます。 選択した方法に応じて、さまざまな長所と短所を得ることができます。 リンクタグを使用する方法を検討することをお勧めしますが、ブラウザーからスタイルシートの読み込みが終了するというイベントが存在しないという問題を排除しました。



コードだけを持っている人のために
define(["text!myCSS.css"], function(cssText) { 'use strict'; var link = document.createElement("link"); link.rel = "stylesheet"; link.type = "text/css" link.href = "data:text/css,"+encodeURI(cssText); var cssLinks = document.querySelectorAll("link[rel=stylesheet]"); if (cssLinks.length > 0) { cssLinks[0].parentElement.insertBefore(link, cssLinks[0]); } else { document.querySelector("head").appendChild(link); } });
      
      







「リンクタグを正確に使用する理由」という質問に対する答えから始めましょう。



実際には、モジュールは通常、視覚表示を便利にカスタマイズできるようにしたいということです。

スタイル属性をマークアップで直接使用する場合、後で再利用するときにこれらの属性を何らかの方法で変更する必要があります。これは非常に不便で柔軟性がありません。



スタイルタグを使用する場合、そのようなスタイルをカスタマイズするには、必要なコンテンツを含むスタイルタグをドキュメントに挿入する必要があるという問題が発生しますが、これもあまり便利ではありません。



linkタグを使用したい場合は、ロードされたスタイルシートの後に独自のスタイルシートを接続し、必要に応じてデフォルトビューを調整するだけです。



上記から、linkタグを使用したオプションが最も柔軟であることがわかります。 コンポーネントを最も多くの方法で使用するときにスタイルを再定義できます。



RequireJSドキュメントに記述されているように、次のコードを使用してcssをロードできます。



 function loadCss(url) { var link = document.createElement("link"); link.type = "text/css"; link.rel = "stylesheet"; link.href = url; document.getElementsByTagName("head")[0].appendChild(link); }
      
      





誰にとっても悪いことではありません。ただし、cssがいつロードされるかを正確に知ることはできません(そして、たとえば、何らかの方法で封印される可能性がある)。 この問題は、ファイルがダウンロードされる前にページがレンダリングされる場合、画像の見苦しい動作を引き起こす可能性があるという事実にも満ちています。



そして、私はこのようなコンポーネントを書きたい:



 define(["text!myCSS.css", "text!myHTML.html"], function(cssText, htmlText) { 'use strict'; ... });
      
      





しかし、結果のCSSテキストをページに詰め込むにはどうすればいいですか? スタイルタグは役立ちますが、以前はオプションがリンクであると判断されました。



提案されたソリューションはデータURLです(誰かがそれを知らない場合は、 こちらで確認できます )。



次のようなものを追加します。



  var link = document.createElement("link"); link.rel = "stylesheet"; link.type = "text/css" link.href = "data:text/css,"+encodeURI(cssText); var cssLinks = document.querySelectorAll("link[rel=stylesheet]"); if (cssLinks.length > 0) { cssLinks[0].parentElement.insertBefore(link, cssLinks[0]); } else { document.querySelector("head").appendChild(link); }
      
      





この方法には、明らかな欠点から間違いなくいくつかの欠点があります-base64エンコードは、データ量を増加させるため、理論的には、一部のブラウザーのURLの長さの制限に遭遇する可能性があります。 しかし、スタイルのボリュームが小さい場合、メソッドは非常に機能しているように見えます。



UPD:

助けてくれたoledje感謝します。base64エンコーディングはテキストには必要ありません。URLエンコーディングはコードを修正しました。



All Articles