JavaScriptでHTML要素の読み込み順序からみるを取得する時の注意点


Web初学者です。Ajaxで取得したHTML要素に対して、JavaScriptが効かない現象に直面しました。調べてみると、これは”読み込み順番”と、それに適切なメソッドを使っていないことが原因でした。自分自身が振り返るための意味も含めて、まとめたいと思います。

そもそもブラウザは、HTMLファイルの上から読み込んでいる

そもそもブラウザは、HTMLファイルの上から順番に読み込んでいる。
以下の例では、上から順番に読み込んでくる為、「かきくけこ」が読み込まれる前にjsが実行されます。

foo.html
<h2>あいうえお<2>
<script>alert("hogehoge");</script>
<h2>かきくけこp<2>

もし、jsを別フィアルに記述して様々なHTML要素を取得して処理を行うとき、そもそもjsが実行される時点でHTML要素が読み込まれていないのは困りますよね。先にHTML要素を全て読み込んでてもらう必要があります。そこで、</body>タグの直前にスクリプトを記述します。こうすれば全ての要素が読み終わってからスクリプトが実行されます。(スマホ普及により、HTMLとスタイルシートを優先的に読み込ませる意味もあるようです。)

jQueryのready()メソッドは要素の準備ができた段階で実行される

先ほどの例では、上から順番に読み込んでしまうが故に、要素を取得できないことを示しました。しかし、jQueryのready()メソッドを使用すれば、その問題を解決できます。readyメソッドでは、選択した要素が取得できた時点で、処理を実行します。例えば、

hoge.html
<script type="text/javascript" src="hoge.js"></script>

  <h1 id="piyo">ハローワールド</h1><script type="text/javascript" src="hoge.js"></script>
hoge.js
$(document).ready(function(){
  $("#piyo").css("color","red");
});

スクリプトを①、②のどちらに記述しても実行結果は変わりません。記述場所にかかわらず、要素(id="piyo")がready(準備OK!)できた時点で、実行されるからです。
ちなみに常識だとは思いますが、$(function(){});は、これの省略系です。”おまじない”じゃなりません!僕はしばらくおまじないとして使ってました。笑

本題:Ajaxで追加された要素をどう取得するか

HTML要素は後から追加される場合もある。代表的なのはAjaxによるページの読み込み。追加された新要素に対しては、ready()メソッドだけでは有効ではないです。

そこで使うのが、on()メソッドです。

qiita.html
<h1 id="piyo">ハローワールド</h1>
qiita.js
$(function(){
    $(document).on('click','#piyo',function() {
        $("#piyo").css("color","red");
    });
});

ここではqiita.htmlをajaxで読み込んだと前提します。そのときにon()ならば、無事に要素(id="piyo")を取得できます。on()メソッドは、セレクターが指定した要素(ここでは$(document))の内側にある要素("#piyo")が、クリックされたタイミングで、それがイベント発生する要素かどうか、を判断しているからです。(らしいです。)
 ※たぶん上記のような書き方はしないと思いますが。。あくまでon()の例です。

最後に

jsがうまく働かない場合は、「ちゃんと読み込まれているかな」をまずは疑え!

以上になります。
ご指摘の箇所が多々あると思います。是非コメントよろしくお願いします。

最後まで読んで頂きありがとうございます。
初学者の私ですが、よろしくお願いします。