28

状況は次のとおりです。2ページあります。

  • 1xhtmlページ
  • 1x外部Javascript

window.onloadこれで、htmlページに、および他のページ固有のメソッド/関数の配置を可能にする内部Javascriptコーディングがあります。

ただし、外部Javascriptでは、window.onloadイベントがトリガーされる前に特定の処理を実行する必要があります。これは、カスタマイズされたコンポーネントを最初に初期化できるようにするためです。

window.onloadイベントがトリガーされる前に外部Javascriptで初期化が行われるようにする方法はあり ますか?

私がこれを尋ねた理由は、再利用可能なコードを作成しようとするためです(一度ビルドすると、すべてを使用します)。外部スクリプトは、メインのhtml / jsp/aspのJavascriptの前に「order/check」にあることを確認する必要があります。 /PHPページが引き継ぎます。また、jQuery @_@で解決策を探していません。

解決策を探すために閲覧したStackOverflowのリンクの一部を次に示します。

誰かが私を助けたり、解決策に導いたりできますか?あなたの助けは大いに感謝されます。


[更新された応答-2012年11月19日]

みなさん、こんにちは。アドバイスと提案された解決策に感謝します。これらはすべて、実行可能な解決策の検索とテストに役立ちました。私は自分の結果に100%満足しているわけではないと感じていますが、あなたのアドバイスと助けが私を解決策に近づけ、実際に同様の状況で他の人を助けるかもしれないことを知っています。

これが私が思いついたものです:

test_page.html

<html>
<head>
<title></title>
<script type="text/javascript" src="loader.js"></script>
<script type="text/javascript" src="test_script_1.js"></script>
<script type="text/javascript" src="test_script_2.js"></script>
<script type="text/javascript">
window.onload = function() {
    document.getElementById("div_1").innerHTML = "window.onload complete!";
}
</script>

<style type="text/css">
div {
    border:thin solid #000000;
    width:500px;
}
</head>
<body>
    <div id="div_1"></div>

    <br/><br/>

    <div id="div_2"></div>

    <br/><br/>

    <div id="div_3"></div>
</body>
</html>

loader.js

var Loader = {
    methods_arr : [],

    init_Loader : new function() {
        document.onreadystatechange = function(e) {
            if (document.readyState == "complete") {
                for (var i = 0; i < Loader.methods_arr.length; i++) {
                    Loader.method_arr[i]();
                }
            }
        }
    },

    load : function(method) {
        Loader.methods_arr.push(method);
    }
}

test_script_1.js

Loader.load(function(){initTestScript1();});

function initTestScript1() {
    document.getElementById("div_1").innerHTML = "Test Script 1 Initialized!";
}

test_script_2.js

Loader.load(function(){initTestScript2();});

function initTestScript2() {
    document.getElementById("div_2").innerHTML = "Test Script 2 Initialized!";
}

これにより、イベントハンドラーを呼び出す前にスクリプトが呼び出されるようにwindow.onloadなりますが、ドキュメントが最初にレンダリングされるようにもなります。

この可能な解決策についてどう思いますか?

助けと助けてくれてありがとう:D

4

4 に答える 4

21

基本的に、あなたはこれを探しています:

document.onreadystatechange = function(e)
{
    if (document.readyState === 'complete')
    {
        //dom is ready, window.onload fires later
    }
};
window.onload = function(e)
{
    //document.readyState will be complete, it's one of the requirements for the window.onload event to be fired
    //do stuff for when everything is loaded
};

詳細については、MDNを参照してください。

DOMがここにロードされる可能性があることに注意してください。ただし、外部jsファイルがロードされているわけではないため、そのスクリプトで定義されているすべての関数/オブジェクトにアクセスできない可能性があります。これを確認する場合は、を使用しwindow.onloadて、すべての外部リソースもロードされていることを確認する必要があります。

したがって、基本的に、外部スクリプトでは、2つのイベントハンドラーが必要になります。1つはreadystatechangeDOMreadyで実行する必要があることを実行するためのもので、もう1つは定義上ドキュメントのに起動されるwindow.onloadです。準備ができています。(これは、ページが完全にロードされているかどうかをチェックします)。
ご存知のとおり、IE <9window.onloadではメモリリークが発生します(DOMとJScriptエンジンは2つの別個のエンティティであるため、windowオブジェクトが完全にアンロードされることはなく、リスナーはGCされません)。これを修正する方法があります。これは私がここに投稿したものですが、かなり冗長ですが、ご存知のとおり...

于 2012-11-07T13:07:10.130 に答える
4

イベントを待たずにすぐに何かを実行したい場合は、JavaScriptで実行できます。コードをすぐに実行するために何もする必要はありません。コード待機。したがって、実際にはイベントを待つよりも簡単です。

たとえば、このHTMLがある場合:

<div id=one></div>
<script src="your-script.js"></script>
<div id=two></div>

次に、your-script.jsにあるコードはすべて、id = oneのdivの後、id=twoのdivが解析される前に実行されます。イベントコールバックを登録せずに、JavaScriptで必要なことをすぐに実行してください。

于 2012-11-07T13:04:36.873 に答える
3

javascriptは上から下に実行されます。つまり、内部JavaScriptの前に外部JavaScriptを含めると、内部JavaScriptが実行される前に実行されるだけです。

于 2012-11-07T13:03:19.557 に答える
1

DOMContentLoadedインターフェイスのイベントを使用することもできWindowます。

addEventListener("DOMContentLoaded", function() {
    // Your code goes here
});

上記のコードは、実際にはイベントリスナーをオブジェクトに追加していますが、オブジェクトはWebページのJavaScriptコードのグローバルスコープでもあるため、window修飾されていません。window.addEventListenerwindow

DOMContentLoadedload画像やウェブページの他の部分がまだ完全にロードされていない場合に発生します。ただし、最初の呼び出しスタック内でDOMに追加されたすべての要素は、このイベントの前にすでに親に追加されていることが保証されています。

于 2018-07-01T20:14:07.250 に答える