DOMContentLoaded と外部スタイルシート。

JavaScriptで、DOMContentLoaded イベントを捕捉して何かしらの処理を行うときの話。

DOMContentLoaded 時に getComputedStyle() でページ内要素のスタイルを取得してごにょごにょしてみたら、どうも上手く行かない。スタイルシートで適用した筈のスタイル値が取得できない場合がある。

困ったときのMDNリファレンス。"注記" として、こんなことが書いてあった。 ざっくり訳すと…

<script>タグより前に <link rel="stylesheet" ... > がある場合、スタイルシートの読み込みが完了するまでスクリプトは実行されません

そういう仕組みなので DOMContentLoaded イベントをより早く発生させるためには、スクリプトを、外部スタイルシート読み込みタグの前に置きなさいよ、と提案してくれているわけですね。

これ、逆に言えば、

<script>タグを <link rel="stylesheet" ... > の前に置くと、スタイルシート読み込みを待たずにスクリプトが走る。すなわち、読み込まれるスタイルシートに記述されているスタイルが適用される前に JavaScript の処理が行われる。

…という仕組みなのだな。つまり、

DOMContentLoaded 時に getComputedStyle() などで、ページ内要素に適用されているスタイルを弄る場合は、
  1. 外部スタイルシートを読み込んでから、
  2. スクリプトが実行される。
…という設定、つまり『<script>タグを <link rel="stylesheet" ... > の後ろに置く』のが正解。

というわけで、試してみる。

外部スタイルシートの読み込みをわざと 5秒 遅延させて挙動を確認してみます。

スタイルシート:ss.css.php】
<?php
header('Content-Type: text/css; charset=utf-8');
sleep(5);
?>
#a{ color:red; }
【1:スタイルシート → スクリプトの順で記述:実際に挙動を確認
<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="ss.css.php">
  <script>
    document.addEventListener( 'DOMContentLoaded',
      function(){
        var a = document.getElementById('a');
        alert( window.getComputedStyle( a ).color );
      },
    false );
  </script>

</head>
<body>
<div id="a">&lt;link rel="stylesheet" ... &gt; → &lt;script&gt; …の順に記述。</div>
</body>
</html>
【2:スクリプト → スタイルシートの順で記述:実際に挙動を確認
<!DOCTYPE html>
<html>
<head>
  <script>
  (...中略...)
  </script>

  <link rel="stylesheet" href="ss.css.php">
</head>
<body>
<div id="a">&lt;script&gt; → &lt;link rel="stylesheet" ... &gt; …の順に記述。</div>
</body>
</html>

どうでしょう。

ブラウザによって少しずつ挙動が異なるようですが、1番目のような順番で記述しておけば、狙ったとおりの "rgb( 255 , 0 , 0 )" という値が取得できますね。

カテゴリ: