イナヅマTVログ

jQueryを使わなくてもDOM readyで処理したい

| 1件のコメント

今やWeb制作で「刺身に醤油でしょ」とも言わんばかりにかならずくっついてくるJavaScript、どうやって開発してますか?
やっぱりライブラリを使いますよねぇ、楽ですから。

jQueryは便利です、大活躍しています。
Dojo ToolkitやMochiKit, Ext JS, prototype.jsも同じように便利です。

JavaScript開発でめんどうなのはEventの処理だと思ってます。
クロスブラウザ対応の一番めんどうなところはライブラリを使えば何も気にせずコードを書けるのはありがたい限りです。

普段はライブラリさんたちの助けを借りて開発しているのですが、お勉強もかねてライブラリを使わずにEvent処理をするとどうなるかを試してみました。
DOMが準備できたら関数を走らせる、を練習がてらコードを書いてみました。
jQueryだったら $(document).ready(function(){}); とあっさり書けてしまいますが、どうなることやら。

/**
 *
 * @param window:WindowElement
 * @param functions:Array [closure1, closure2,...]
 */
(function (window, functions) {
    var document = window.document,
    functions = functions && functions.splice ? functions : [],
    ie = document.addEventListener ? false : true,
    complete = false,
    dispose = function () {
        if (complete) {
            return;
        };
        complete = true;
        if (!ie) {
            document.removeEventListener('DOMContentLoaded', onDOMContentLoaded);
            document.removeEventListener('readystatechange', onReadyStateChange);
            window.removeEventListener('load', onWindowLoad);
        } else {
            document.detachEvent('onreadystatechange', onReadyStateChange);
            window.detachEvent('onload', onWindowLoad);
        }
        for (var i = 0, limit = functions.length; i < limit; i++) {
            setTimeout(functions[i], 25 * i);
        }
    },
    onDOMContentLoaded = function (e) {
        dispose();
    },
    onReadyStateChange = function (e) {
        if (document.readyState == 'complete') {
            dispose();
        }
    },
    onWindowLoad = function (e) {
        dispose();
    }
    ;// end of variables
 
    if (!ie) {
        document.addEventListener('DOMContentLoaded', onDOMContentLoaded, false);
        document.addEventListener('readystatechange', onReadyStateChange, false);
        window.addEventListener('load', onWindowLoad, false);
    } else if (document.attachEvent) {
        document.attachEvent('onreadystatechange', onReadyStateChange);
        window.attachEvent('onload', onWindowLoad);
    }
}(window,
    [
        function () {console.log('function 1')},
        function () {console.log('function 2')},
        function () {console.log('function 3')}
    ]
));

こんな感じかなぁ。
一応動いたみたい。
addEventListenerとattachEventのどっちも使えないブラウザがあったらお手上げだけど…

IE6だとdetachEventが間に合わない(?)みたいでonReadyStateChangeの’complete’が2回走るみたい。
これ、jQueryの1.4.3~1.4.4のバグと同じ現象かな。
だったらIE6が悪かったんだなぁ。

こうやって自力でコードを書いてみるとjQueryをはじめとするライブラリの偉大さとありがたさがひしひしと身にしみます。

【処理フロー】<- 説明不足だったので追記します ・DOMContentLoaded が使えるなら使う DOMContentLoaded イベントが発生したらDOMの準備ができたことになります。 代替手段(1) ・readystatechange を監視する。 document.readyState が "complete" だとDOMの準備ができたことになります。 代替手段(2) ・DOMContentLoaded と readystatechange のどちらも使えない時は window.onload で処理する タイミング的には全ての読み込みが終わってになるので「DOMの準備ができたら」よりは遅くなりますが全てのブラウザで対応できるはずです。 【追記】 今回のコードを実践に投入することはないでしょう。 自前のなんちゃってイベント処理よりもJavaScriptヒーロー作のライブラリを使った方が精神衛生上も安心です。 ライブラリ内部でもイベントは同じような処理をしているのだろうと想像できますが、より緻密に様々なブラウザで検証し提供されていることでしょう。 参考書籍

1件のコメント

  1. ピンバック: 超個人的メモ, JavaScript関連の投稿リンクをまとめておく « イナヅマtvログ

コメントを残す