web-dev-qa-db-ja.com

window.onloadを使用するためのベストプラクティス

私はJoomlaのWebサイト/コンポーネント/モジュールとプラグインを開発していますが、ページがロードされるとイベントをトリガーするJavaScriptを使用する機能が必要になることがよくあります。ほとんどの場合、これはwindow.onload関数を使用して行われます。

私の質問は:

  1. これは、ページの読み込み時にJavaScriptイベントをトリガーする最良の方法ですか、それともより良い/新しい方法がありますか?
  2. これがページのロード時にイベントをトリガーする唯一の方法である場合、複数のイベントを異なるスクリプトで実行できるようにする最良の方法は何ですか?
37
privateace

window.onload = function(){};は機能しますが、お気づきかもしれませんが、リスナーを1つだけ指定できますです。

これを行うためのより良い/新しい方法は、フレームワークを使用するか、ネイティブaddEventListenerおよびattachEvent(IE用)メソッドの単純な実装を使用することです。イベントのリスナーもremoveできます。

クロスブラウザ実装は次のとおりです。

_// Cross-browser implementation of element.addEventListener()
function listen(evnt, elem, func) {
    if (elem.addEventListener)  // W3C DOM
        elem.addEventListener(evnt,func,false);
    else if (elem.attachEvent) { // IE DOM
         var r = elem.attachEvent("on"+evnt, func);
         return r;
    }
    else window.alert('I\'m sorry Dave, I\'m afraid I can\'t do that.');
}

// Use: listen("event name", elem, func);
_

Window.onloadの場合:listen("load", window, function() { });


[〜#〜] edit [〜#〜]他の人から指摘された貴重な情報を追加して回答を拡大したいと思います。

これはDOMContentLoaded(Mozilla、Operaおよび現在Webkitナイトリーがこれをサポートしている)およびonreadystatechange(IEの場合)eventsこれはdocumentオブジェクトがドキュメントを操作できる状態になったことを理解するために適用できます(すべての画像/スタイルシートなどがロードされるのを待たずに)。

これをクロスブラウザでサポートするための「ハッキングな」実装が多数あるため、この機能にはフレームワークを使用することを強くお勧めします。

44
Luca Matteis

最新のjavascriptフレームワークは、「ドキュメント対応」イベントのアイデアを導入しています。これは、ドキュメントでDOM操作を実行する準備ができたときに発生するイベントです。 「onload」イベントは、ページのすべてがロードされた後にのみ発生します。

「ドキュメントの準備ができた」イベントに加えて、フレームワークは、イベントが発生したときに実行するJavascriptコードと関数の複数のビットをキューに入れる方法を提供しました。

したがって、フレームワークに反対する場合、これを実行する最善の方法は、独自のdocument.onloadキューを実装することです。

フレームワークに反対していない場合は、 jQuery and document.readyPrototype and dom:loadedDojo and addOnLoad または[フレームワーク]および[ドキュメント準備完了]のGoogle。

フレームワークを選択していないが興味がある場合は、jQueryを開始するのに適した場所です。 Javascriptのコア機能は変更されず、通常は邪魔にならず、必要なときに好きなように操作できます。

10
Alan Storm

Window.onloadイベントは、複数の作成でオーバーライドされます。関数を追加するには、window.addEventListener(W3C standard)またはwindow.attachEvent(IEの場合)を使用します。動作した次のコードを使用します。

if (window.addEventListener) // W3C standard
{
  window.addEventListener('load', myFunction, false); // NB **not** 'onload'
} 
else if (window.attachEvent) // Microsoft
{
  window.attachEvent('onload', myFunction);
}
10
Devaroop

JoomlaにはMooToolsが付属しているため、追加のコードにMooToolsライブラリを使用するのが最も簡単です。 MooToolsには、ページが読み込まれ、ドキュメントツリーが解析されるときに起動するdomreadyと呼ばれるカスタムイベントが付属しています。

window.addEvent( domready, function() { code to execute on load here } );

MooToolsの詳細については、 こちら をご覧ください。 Joomla 1.5には現在MT1.1が付属していますが、Joomla 1.6アルファにはMT1.2が含まれます

2
Arlen

個人的には、私は この方法 を好みます。複数のonload関数を持つことができるだけでなく、何らかのスクリプトがそれを定義した場合before、このメソッドそれを処理するのに十分です...残っている唯一の問題は、ページがwindow.addLoad()関数を使用しない複数のスクリプトをロードする場合です。しかし、それは彼らの問題です:)。

追伸後でより多くの機能を「チェーン」したい場合にも最適です。

1
Mike

これは汚いですが短い方法です:P

function load(){
   *code*
}

window[ addEventListener ? 'addEventListener' : 'attachEvent' ]
( addEventListener ? 'load' : 'onload', function(){} )
1
Aamir Afridi

私は常にドキュメントの下部にjQuery/bootstrap JSファイルを含めており、$ドキュメント上で、ページの最上部に含める唯一のJSスクリプトである小さな「init」プラグインを開発しました。

window.init = new function() {
    var list = [];

    this.Push = function(callback) {
        if (typeof window.jQuery !== "undefined") {
            callback();
        } else {
            list.Push(callback);
        }
    };

    this.run = function() {

        if (typeof window.jQuery !== "undefined") {
            for(var i in list) {
                try {
                    list[i]();
                } catch (ex) {
                    console.error(ex);
                }
            }
            list = [];
        }
    };

    if (window.addEventListener) {
        window.addEventListener("load", this.run, false);
    } else if (window.attachEvent) {
        window.attachEvent("onload", this.run);
    } else {
        if (window.onload && window.onload !== this.run) {
            this.Push(window.onload);
        }
        window.onload = this.run;
    }
};

これを使用して、jQueryおよびbootstrap=を含める前に、ページ上に匿名ローダーを定義し、jQueryが存在すると起動することを確認できます。

init.Push(function() {

    $('[name="date"]').datepicker({
        endDate: '0d',
        format: 'yyyy-mm-dd',
        autoclose: true
    }).on('hide', function() {
        // $.ajax
    });

    $('[name="keyword_id"]').select2();
});
0
yergo