DOMContentLoaded と外部スタイルシート。
JavaScriptで、DOMContentLoaded イベントを捕捉して何かしらの処理を行うときの話。
DOMContentLoaded 時に getComputedStyle() でページ内要素のスタイルを取得してごにょごにょしてみたら、どうも上手く行かない。スタイルシートで適用した筈のスタイル値が取得できない場合がある。
困ったときのMDNリファレンス。"注記" として、こんなことが書いてあった。 ざっくり訳すと…
<script>タグより前に <link rel="stylesheet" ... > がある場合、スタイルシートの読み込みが完了するまでスクリプトは実行されません。
そういう仕組みなので DOMContentLoaded イベントをより早く発生させるためには、スクリプトを、外部スタイルシート読み込みタグの前に置きなさいよ、と提案してくれているわけですね。
これ、逆に言えば、
<script>タグを <link rel="stylesheet" ... > の前に置くと、スタイルシート読み込みを待たずにスクリプトが走る。すなわち、読み込まれるスタイルシートに記述されているスタイルが適用される前に JavaScript の処理が行われる。
…という仕組みなのだな。つまり、
DOMContentLoaded 時に getComputedStyle() などで、ページ内要素に適用されているスタイルを弄る場合は、
- 外部スタイルシートを読み込んでから、
- スクリプトが実行される。
というわけで、試してみる。
外部スタイルシートの読み込みをわざと 5秒 遅延させて挙動を確認してみます。
【スタイルシート:ss.css.php】
<?php
header('Content-Type: text/css; charset=utf-8');
sleep(5);
?>
#a{ color:red; }
【1:スタイルシート → スクリプトの順で記述:実際に挙動を確認】
header('Content-Type: text/css; charset=utf-8');
sleep(5);
?>
#a{ color:red; }
<!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"><link rel="stylesheet" ... > → <script> …の順に記述。</div>
</body>
</html>
【2:スクリプト → スタイルシートの順で記述:実際に挙動を確認】
<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"><link rel="stylesheet" ... > → <script> …の順に記述。</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<script>
(...中略...)
</script>
<link rel="stylesheet" href="ss.css.php">
</head>
<body>
<div id="a"><script> → <link rel="stylesheet" ... > …の順に記述。</div>
</body>
</html>
<html>
<head>
<script>
(...中略...)
</script>
<link rel="stylesheet" href="ss.css.php">
</head>
<body>
<div id="a"><script> → <link rel="stylesheet" ... > …の順に記述。</div>
</body>
</html>
どうでしょう。
ブラウザによって少しずつ挙動が異なるようですが、1番目のような順番で記述しておけば、狙ったとおりの "rgb( 255 , 0 , 0 )" という値が取得できますね。
コメント