Javascriptのロードと実行

伊谢尔伦
伊谢尔伦オリジナル
2016-11-22 13:12:061065ブラウズ

まず最初に、JavaScript の読み込みと実行について話したいと思います。一般に、ブラウザには Javascript の実行に関する 2 つの大きな特徴があります。1) Javascript はロード直後に実行されます。2) 実行されると、それ以降のページのコンテンツ (ページのレンダリングや他のリソースのダウンロードを含む) がブロックされます。したがって、複数の js ファイルがインポートされる場合、ブラウザーでは、これらの js ファイルがシリアルにロードされ、順番に実行されます。

JavaScript は HTML ドキュメントの DOM ツリーを操作する可能性があるため、ブラウザーは一般に、CSS ファイルのように js ファイルを並行してダウンロードしません。これは、js ファイルの特殊性によって引き起こされるためです。したがって、JavaScript が後続の DOM 要素を操作したい場合、基本的にブラウザはオブジェクトが見つからないというエラーを報告します。 Javascript が実行されると、後続の HTML がブロックされ、DOM ツリー内に後続の DOM ノードが存在しないためです。したがって、プログラムはエラーを報告しました。

従来の方法

したがって、コード内に次のコードを記述すると、

<scripttype="text/javascript"  src="http://coolshell.cn/asyncjs/alert.js"></script>

基本的に、ヘッド内の 3f1c4e4b6b16bbbd69b2ee476dc4f83a タグは、後続のリソースの読み込みとページ全体の生成をブロックします。見ていただくために特別な例を作成しました: 例 1。 注: 私のalert.jsにはalert("hello world")という一文しかありません。これにより、JavaScriptが次のものをどのようにブロックするかを簡単に確認できます。

これで、多くの Web サイトが Web ページの最後に JavaScript を配置したり、window.onload や docmuemt Ready などのイベントを使用したりする理由がわかりました。

さらに、ほとんどの Javascript コードはページを待つ必要がないため、非同期読み込み機能があります。では、どうやって非同期に読み込むのでしょうか?

document.write メソッド

したがって、document.write() はブロックせずに問題を解決できると考えるかもしれません。もちろん、document.write で 3f1c4e4b6b16bbbd69b2ee476dc4f83a タグを記述した後、次のことを実行できると思われるでしょうが、これは正しいことです。これは同じ script タグ内の Javascript コードに当てはまりますが、ページ全体では依然としてブロックされます。 以下はテスト コードの一部です:

<scripttype="text/javascript"language="javascript">
    function loadjs(script_filename) {
        document.write(&#39;<&#39; + &#39;script language="javascript" type="text/javascript"&#39;);
        document.write(&#39; src="&#39; + script_filename + &#39;">&#39;);
        document.write(&#39;<&#39;+&#39;/script&#39;+&#39;>&#39;);
        alert("loadjs() exit...");
    }
    var script = &#39;http://coolshell.cn/asyncjs/alert.js&#39;;
    loadjs(script);
    alert("loadjs() finished!");
</script>
<scripttype="text/javascript"language="javascript">
   alert("another block");
</script>

アラートの順序は何だと思いますか?さまざまなブラウザで試すことができます。閉じたいテスト ページは次のとおりです: 例 2。

スクリプトの defer 属性と async 属性

IE は、IE6 以降、次のような defer タグをサポートしています。

<scriptdefertype="text/javascript"src="./alert.js">
</script>

IE の場合、このタグにより、IE は js ファイルを並行してダウンロードし、DOM 全体が完了するまで実行を保留します。 (DOMContentLoaded)、複数の defer 3f1c4e4b6b16bbbd69b2ee476dc4f83a も実行時に表示される順序で実行されます。最も重要なことは、3f1c4e4b6b16bbbd69b2ee476dc4f83a が遅延に追加された後、後続の DOM レンダリングをブロックしないことです。ただし、この遅延は IE のみに適用されるため、一般的にはあまり使用されません。

私たちの標準 HTML5 には、JavaScript の非同期読み込み用の属性 (async) も追加されています。どのような値を割り当てても、それが表示されている限り、js ファイルの非同期読み込みが開始されます。ただし、async の非同期ロードには重大な問題があります。つまり、「ロード後すぐに実行する」という軍事ルールを忠実に実行しているため、ページのレンダリングを妨げることはありませんが、順序とタイミングを制御することができません。彼の処刑の様子。この例を見て感覚を掴んでください。

非同期タグをサポートするブラウザは、Firefox3.6+、Chrome 8.0+、Safari 5.0+、IE 10+、Opera はまだサポートしていないため (ここから)、この方法はあまり良くありません。すべてのブラウザがそれを実行できるわけではないためです。

DOMメソッドの動的作成

おそらくこのメソッドが最もよく使われます。

functionloadjs(script_filename) {
    varscript = document.createElement(&#39;script&#39;);
    script.setAttribute(&#39;type&#39;,&#39;text/javascript&#39;);
    script.setAttribute(&#39;src&#39;, script_filename);
    script.setAttribute(&#39;id&#39;,&#39;coolshell_script_id&#39;);
    script_id = document.getElementById(&#39;coolshell_script_id&#39;);
    if(script_id){
        document.getElementsByTagName(&#39;head&#39;)[0].removeChild(script_id);
    }
    document.getElementsByTagName(&#39;head&#39;)[0].appendChild(script);
}
varscript =&#39;http://coolshell.cn/asyncjs/alert.js&#39;;
loadjs(script);

このメソッドは、js ファイルを非同期でロードするためのほぼ標準的な方法となっています。このメソッドのデモについては、例 3 を参照してください。このメソッドは JSONP でも活用されています。つまり、スクリプトの src にバックグラウンド スクリプト (PHP など) を指定できます。この PHP は、パラメーターが json 文字列である JavaScript 関数を返し、事前定義された JavaScript を呼び出します。関数。この例を見てみましょう: t.js (この例は、以前 Weibo で収集した非同期 Ajax 呼び出しの小さな例です)

オンデマンドで js を非同期にロードします

上記の DOM メソッドの例は、非同期の問題を解決します読み込み中 JavaScript を挿入する問題は解決されませんが、指定した時間に Javascript を実行したいという問題は解決されません。したがって、上記の DOM メソッドを特定のイベントに結び付けるだけで済みます。

例:

window.load イベントにバインド - 例 4

例 4 と例 3 の実行の違いを比較する必要があります。両方の例で特にコードを使用しました。実行を見てください。コードを強調表示したスクリプトと、alert.js の実行、違いがわかるでしょう)

window.load = loadjs("http://coolshell.cn/asyncjs/alert.js")

特定のイベントにバインド - 例 5

<p style="cursor: pointer"onclick="LoadJS()">Click to load alert.js </p>

    这个示例很简单了。当你点击某个DOM元素,才会真正载入我们的alert.js。

更多

但是,绑定在某个特定事件上这个事似乎又过了一点,因为只有在点击的时候才会去真正的下载js,这又会太慢了了。好了,到这里,要抛出我们的终极问题——我们想要异步地把js文件下载到用户的本地,但是不执行,仅当在我们想要执行的时候去执行。

要是我们有下面这样的方式就好了:

varscript = document.createElement("script");
script.noexecute =true;
script.src ="alert.js";
document.body.appendChild(script);
//后面我们可以这么干
script.execute();

    可惜的是,这只是一个美丽的梦想,今天我们的Javascript还比较原始,这个“JS梦”还没有实现呢。

所以,我们的程序员只能使用hack的方式来搞。

有的程序员使用了非标准的script的type来cache javascript。如:

<scripttype=cache/scriptsrc="./alert.js"></script>

    因为”cache/script”,这个东西根本就不能被浏览器解析,所以浏览器也就不能把alert.js当javascript去执行,但是他又要去下载js文件,所以就可以搞定了。可惜的是,webkit严格符从了HTML的标准——对于这种不认识的东西,直接删除,什么也不干。于是,我们的梦又破了。

所以,我们需要再hack一下,就像N多年前玩preload图片那样,我们可以动用object标签(也可以动用iframe标签),于是我们有下面这样的代码:

functioncachejs(script_filename){
    varcache = document.createElement(&#39;object&#39;);
    cache.data = script_filename;
    cache.id ="coolshell_script_cache_id";
    cache.width = 0;
    cache.height = 0;
    document.body.appendChild(cache);
}

    然后,我们在的最后调用一下这个函数。请参看一下相关的示例:示例六

在Chrome下按 Ctrl+Shit+I,切换到network页,你就可以看到下载了alert.js但是没有执行,然后我们再用示例五的方式,因为浏览器端有缓存了,不会再从服务器上下载alert.js了。所以,就能保证执行速度了。

关于这种preload这种东西你应该不会陌生了。你还可以使用Ajax的方式,如:

varxhr =newXMLHttpRequest();
xhr.open(&#39;GET&#39;,&#39;new.js&#39;);
xhr.send(&#39;&#39;);

    到这里我就不再多说了,也不给示例了,大家可以自己试试去。

最后再提两个js,一个是ControlJS,一个叫HeadJS,专门用来做异步load javascript文件的。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。