JQueryの$(document).readyについて




docready

ダウンロードしてきたプラグインが動かない?

みなさんがwebページを作成する際に何らかの機能をつけたくて(例えば、写真のスライドショーを作りたい、クリックで開閉するメニューを作りたい、など)少し調べてみると、どうやらJQueryのプラグインを導入するとこういった機能が簡単に実現できるらしい、じゃあこれを一回使ってみるかとダウンロードして使ってみるとちゃんと動かない、ということがあるかもしれません。そのプラグインを解説しているサイトや、配布元のドキュメントを見ても一見正しく記述されているように見えるのになんで?という時にチェックするポイントとして「そのプラグインって$(document).readyの中に書かないと動かないのでは?」というものがあります。

具体例

例えば、筆者がスライドショーを実装する際によく使うプラグインがSlickというプラグインです。 このプラグインを使おうと思ってリンク先上部のコードをhtml内に

<script>
    $('.single-item').slick();
</script>

と書くとこのスクリプトは動きません。(.your-classはスライドショーにしたいimgなどを囲っているdivとか)

そこでさらにページ下部の「usage」のところを見ると以下のようになっています。 こちらは動きます。

<script>
    $(document).ready(function(){
        $('.your-class').slick({
            setting-name: setting-value
        });
    });
</script>

上記コードの

setting-name: setting-value

の部分はslickのパラメータ設定の部分なので違いは、slickを初期化して動作させるコードが$(document).ready()の中に入っているかどうかですね。

$(document).ready()って?

それでは、あるプラグインが動作したりしなかったりするのに関係するらしい$(document).ready()とはなんでしょうか? この$(document).ready()はJQuery独特のイベントで「ページを記述しているhtml(document)が読み込み終わったら(ready)」$(document).ready(なんかのコード)の()内のコードを実行するよ、ということを言っているのです。 一般的には

$(document).ready(function(){ //実行したいコード });

と書くことが多いです。

なぜこのような機能が必要になるのでしょうか?それは、ブラウザはhtmlファイルの内容を表示しようとする際、その内容を上から順番に読み込んでいき、javascriptのコードがあれば読み込んだタイミングで実行しようとすることと関係があります。

よくあるサンプルでは、先ほどのslickの具体例のようなコードはheadタグ内に書かれることが多いですが、 もしも、具体例の上のように書くとheadまでの内容しか読み込まれていない段階で本来bodyタグ内に入っているであろう.your-classに対してslickというプラグインの機能を実行しようとします。当然ブラウザはまだbodyの内容は読み込んでいないので、「your-classなんていうクラスの要素はないよ!」ということで実行エラーになります。 つまり、このプラグインが動作するには、少なくともbody内に書かれているclass=your-classとなっている要素が読み込まれる必要があるのですね。

このようにページの内容の読み込みを「待ってから」何らかの処理を行う、というタイミングを指定するのが$(document).readyの役割です。(正確にはDOM要素と呼ばれるページ構成の読み込みが完了したタイミングになります。DOM要素に関しては結構ややこしいので正しいHTMLとドキュメントツリーを理解しようなどが参考になります)

注意

上で書いたように「ページの読み込みを待ってから」というタイミングを指定する$(document).readyですが、少し書いたようにこれは正確には「ブラウザがhtmlソースからDOM要素を構築し、読み込み終わったら」というタイミングであることに注意する必要があります。

なぜなら、このタイミングは我々人間が思う「ページが表示されたら」というタイミングとはずれているからです。どういうことかというと、この時点ではまだ、画像などまだ読み込まれていない要素、というものが存在するのです。 なので、JQueryを使って画像に対して何かの加工を行う、とかその大きさを取得する、などという処理を行う場合は$(document).ready内で処理すると失敗することがあります(たまたま画像が読み込まれていて処理が行えることもあります)。

それではこのように「ページの内容が完全に読み込まれてから」何かの処理を行いたい、という場合はどうすればいいの?ということになるのですが、このような場合は$(document).readyとは別に

$(window).load()

という書き方ができます。これはページの内容が画像なども含めて完全に読み込まれた後に()内のコードを実行する、というタイミングを指定する書き方なので、画像などを扱う場合はこちらを使う必要があるかもしれません。

このように、実行したい処理によって色々と実行タイミングを調整する必要があり、そのために$(document).ready()や$(window).load()などを使い分けることでいろいろなプラグインを便利に使ってみましょう。