画像が読み込まれたタイミングで jQuery コードを実行する

2014年9月25日 20:03

まず大原則として、jQuery のコードの実行タイミングは「DOM が利用可能になったとき」である、と。<div id="hoge"></div> にアクセスするために $('#hoge') と書いたとしても、DOM が利用可能になっていなければ当該要素を見つけられず何もできない。なので、世の中の jQuery のコードは大体以下のような体裁で書かれている。

$(document).ready(function() {
    // 処理
});

この記法には省略形があり、筆者はもっぱら以下を使っている。jQuery の公式ドキュメントにも「shorthand for $(document).ready()」として記されている。

$(function() {
    // 処理
});

これら以外にも body 要素の onload イベントを用いる方法や、jQuery 絡みのスクリプトをページの下(</body> のすぐ上)にまとめて書く方法など様々な流派(?)があるようだが、そこはやはり公式でもある $(document).ready() 記法に従ったほうがベターだと思う。というのも、jQuery 日本語リファレンスにこんな記述があるからだ。

通常よく使われる body の onload などでは、ページ上の画像などもロードされ、レンダリングもされた状態で動作し始めるために、ユーザのオペレーションが開始されてしまう可能性があります。

さて本題だが、$(document).ready() 内の function は(読んで字のごとく)Document が Ready 状態になったタイミングで実行される。つまり、ページ上の画像などはその後にロードされ始めるため、画像を内包するボックス要素の高さを取得した場合などには不都合が生じる。img タグに height 属性が指定してあれば問題ないが、API 経由で取得したサイズがまちまちな画像を表示する場合などはその方法も採れない。よって、body 要素の onload イベントのように「ページの構成要素がすべて読み込み終わったタイミング」で実行させる必要がある。

じつはこれは意外に簡単で、以下のように書き換えればいい。

$(window).load(function() {
    // 処理
});

あと、蛇足になるが、ツイート中にある「float で並べたボックス要素の高さを揃えるスクリプト」(拙作)も記しておく。第1引数が揃えたいボックス要素のエレメント、第2引数が1行に並べる個数である。

function equalHeight($el, num) {
    var count = 1;
    var tallest = 0;
    var cols = [];
    $el.each(function() {
        if ($(this).height() > tallest) {
            tallest = $(this).height();
        }
        cols.push(this);
        if (count % num == 0) {
            for (var i = 0; i < num; i++) {
                $(cols[i]).height(tallest);
            }
            tallest = 0;
            cols = [];
        }
        count++;
    });
}