< 目次フレームを自動生成する | 続、目次フレームを自動生成する >

January 6, 2010

window.onload を待たずに処理を開始する

Web ページの読み込み時に処理をさせる場合、何の疑問も持たずに window.onload を使っていたんですが、このハンドラは DOM ツリーだけじゃなくて画像まで全部読込んでから実行されるらしいです。知らんかった…。

で、そうじゃなくて DOM ツリーが生成されたタイミングで処理を開始したいなーってことで、あちこちのサイトでそんな Tips が取り上げられてるんですが、よんでもいまひとつ理解できない…。

なので調べつつ、結局自分でスクリプトを書き直してみました。こちらのブログ記事がよくまとまっていて大変参考になりました。あと、元ネタにあたるこちらとかこちらとか…。

var LoadListener = function ()
    {
        // イベントをリスン
        var addEvent = function (element, eventName, fn, useCapture)
            {
                if (element.addEventListener)
                    element.addEventListener (eventName, fn, useCapture);
                else if (element.attachEvent)
                    return element.attachEvent ('on' + eventName, fn);
                else 
                    element ['on' + eventName] = fn;
                return true;
            }

        // 初期処理実行
        var exechandler = function ()
            {
                // 二重呼び出しチェック
                if (arguments.callee.done) return;
                arguments.callee.done = true;

                // タイマ解除
                if (typeof _timer != 'undefined')
                {
                    clearInterval (_timer);
                    _timer = null;
                }

                // 実行
                LoadListener.onload ();
            };

        // タイマ関数
        var ontimer = function ()
            {
                if (/loaded|complete/.test (document.readyState))
                    exechandler ();
            };

        // public 実装
        return {

            // 読み込み時に実行する処理
            onload: function () {},

            // UA ごとの設定を行う
            init: function ()
                {
                    // Mozilla/Opera9
                    if (document.addEventListener)
                        document.addEventListener ("DOMContentLoaded", exechandler, false);

                    // Chrome/Safari
                    else if (/webkit|safari|khtml/i.test (navigator.userAgent))
                        var _timer = setInterval (ontimer, 10);

                    else
                    {
                        // IE
                        /*@cc_on @*/
                        /*@if (@_win32)
                        document.write ('<script id="__ie_onload" defer src="javascript:void (0)"><\/script>');
                        document.getElementById ("__ie_onload").onreadystatechange = function ()
                            {
                                if (this.readyState == "complete")
                                    exechandler ();
                            };
                        @else @*/
                        addEvent (window, "load", exechandler, false);
                        /*@end @*/
                    }
                }
        };
    } ();
LoadListener.init ();

トラックバック

このエントリーにトラックバック:
http://frog.raindrop.jp/cgi-bin/mt/mt-tb.cgi/2472

コメント

コメントする

※ コメントスパム対策のため、コメント本文はおはよう、こんにちわ、こんばんわのいずれかより始めるようにしてください。

name:
email:

※ 必要ですが、表示しません。

url:
情報を保存する ?