ホームページ > 記事 > ウェブフロントエンド > Javascriptのロードと実行
まず最初に、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('<' + 'script language="javascript" type="text/javascript"'); document.write(' src="' + script_filename + '">'); document.write('<'+'/script'+'>'); alert("loadjs() exit..."); } var script = 'http://coolshell.cn/asyncjs/alert.js'; 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('script'); script.setAttribute('type','text/javascript'); script.setAttribute('src', script_filename); script.setAttribute('id','coolshell_script_id'); script_id = document.getElementById('coolshell_script_id'); if(script_id){ document.getElementsByTagName('head')[0].removeChild(script_id); } document.getElementsByTagName('head')[0].appendChild(script); } varscript ='http://coolshell.cn/asyncjs/alert.js'; 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('object'); 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('GET','new.js'); xhr.send('');
到这里我就不再多说了,也不给示例了,大家可以自己试试去。
最后再提两个js,一个是ControlJS,一个叫HeadJS,专门用来做异步load javascript文件的。