しゃのんあどべんとかれんだー 3日目 (JavaScript の DOMContentLoaded について、ちょっとしたおはなし)

このエントリーをはてなブックマークに追加

この記事は Shanon Advent Calendar 2015 の 3日目の記事です。

というわけで、本日も私 munepom ( @__munepom__ ) がお送りします。
本日も飲み会後の帰宅のため、どうしよう。。。30分で書けるネタが。。。あ、ありました。

JavaScript の初歩的なおはなしでございます。

ある HTML 要素に対して何かを行いたい場合、その要素を取得できねばなりませんね。
<div id="Hoge"></div> 要素に対して、何かテキストを加えたい場合を想定します。
document.querySelector が使えるならば、
document.querySelector("#Hoge") と書くと、HTML Element Object を取得できます。
querySelector 非対応ブラウザの場合、document.getElementById("Hoge") を利用すれば良いですね。
ところが、普通に

<script>
var elm = document.querySelector("#Hoge") || document.getElementById("Hoge");
elm.innerHTML = "fuga"; // XSS の危険性があるので、innerHTML の利用には気をつけてね!
</script>
<div id="Hoge"></div>
と書くと、
Uncaught TypeError: Cannot set property 'innerHTML' of null
という例外が発生してしまいます。
この時、console.log(elm) を実行すると、elm = null となっています。

下記のように、<script> タグを取得したい要素よりも後に記述すると、
要素を取得でき、スクリプトを実行できますね。

<div id="Hoge"></div>
<script>
var elm = document.querySelector("#Hoge") || document.getElementById("Hoge");
elm.innerHTML = "fuga"; // XSS の危険性があるので、innerHTML の利用には気をつけてね!
</script>
5年前、社会人になりたてホヤホヤで Java と JavaScript の区別もついていなかった頃、
どこにでも好きなスクリプトを読み込めて実行できるには、どうすれば良いのでしょうか?と悩みました。
onload イベントにフックした場合は、画面描画完了後にスクリプトが実行されるようですし。。。

そこで、DOMContentLoaded の登場です。

DOMContentLoaded は、HTML5 に準拠した仕様のようですね。
DOM 構築が完了したことを知らせてくれるので、このイベントにフックしてスクリプトを実行すれば、
画面を描画する前に DOM を変更して目的とする画面などを構築したり、他の操作を実行したりできます。

というわけで、下記のようなスクリプトへ修正すると、<script> タグの位置に関わらず、目的とする要素を操作できます。

<script>
document.addEventListener("DOMContentLoaded", function(e){
    var elm = document.querySelector("#Hoge") || document.getElementById("Hoge");
    elm.innerHTML = "fuga";
});
</script>
<div id="Hoge"></div>

あ、ここまで書いといてナンですが、、、
DOMContentLoaded は、Firefox、Chrome、Safari といった主要ブラウザではほぼ動作するはずですが、
IE の場合は、少なくとも IE9 以降でないと対応していなかったはずですので、ご注意願います。

どうしても IE8 以前を使う場合は、
『doScrollメソッドだけはDOM構築後,onload イベント前に実行できる』
という性質を利用するのが良いかと。
(少々古いですが、jQuery 1.7.2 の bindReady を読み解くと良いと思います。)

Enjoy! (・ω・)ノ

次の記事
« Prev Post
前の記事
Next Post »
Related Posts Plugin for WordPress, Blogger...