web-dev-qa-db-ja.com

ページ内のスクリプトタグの場所は、その中で定義されているJavaScript関数にどのように影響しますか?

JavaScript関数は<head>タグで定義する必要があると読みましたが、<script>の場所は<head><body>、またはその他のタグで)JavaScript関数に影響します。

具体的には、関数のスコープと呼び出し元にどのような影響を与えますか?

javascripthtmlfunctiontags
43
Mark Rogers

頭に<SCRIPT>のみを追加するように言うsoundsとするのは合理的なことですが、他の人が言っているように、これには多くの理由があります推奨されておらず、実用的でもありません。主に速度とHTMLページが動的に生成される方法です。

これが HTML 4の仕様による です。

SCRIPT要素は、ドキュメント内にスクリプトを配置します。この要素は、HTMLドキュメントのHEADまたはBODYに何度でも出現する可能性があります。

そして、いくつかのサンプルHTML。すべてがここでフォーマットされているように見えませんか:)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
     "http://www.w3.org/TR/html4/strict.dtd">
<HTML>
<HEAD>
<TITLE>A document with SCRIPT</TITLE>
<META http-equiv="Content-Script-Type" content="text/tcl">
<SCRIPT type="text/vbscript" src="http://someplace.com/progs/vbcalc">
</SCRIPT>
</HEAD>
<BODY>
<SCRIPT type="text/javascript">
...some JavaScript...
</SCRIPT>
</BODY>
</HTML>

そして、楽しみにしています HTML 5

<SCRIPT>の新しい非同期属性:

注:スクリプトを実行する方法はいくつかあります。

Async属性が「true」の場合:スクリプトはページの残りの部分と非同期で実行されるため、ページが解析を続行している間にスクリプトが実行されます。

Async属性は「false」ですが、defer属性は「true」です。スクリプトは、ページの解析が終了したときに実行されます。

26
Simon_Weaver

The most convenient and reliable file storage service

Receive your personal cloud storage with 2Gb of space for free

通常の遊びのルールはまだ残っています。それが定義される前にものを使用しないでください。 :)

また、「すべてを一番下に置く」というアドバイスは、本の規則だけではないことに注意してください-場合によっては、実行できない場合があります他の場合では、スクリプトを別の場所に置く方が理にかなっています。

ドキュメントの下部にスクリプトを配置する主な理由は、パフォーマンスのためです。他のHTTPリクエストとは異なり、スクリプトは並行して読み込まれません。つまり、残りのページの読み込みが遅くなります。スクリプトを下部に配置するもう1つの理由は、「DOM対応」関数を使用する必要がないためです。スクリプトタグはすべての要素の下にあるので、DOMは操作の準備ができています!

編集:これを読んでください: http://developer.yahoo.com/performance/rules.html#js_bottom

19
James

配置の側面の1つはパフォーマンスです。ドキュメントの下部に配置することが推奨される場合がある理由については、 YSlowディスカッション内のこの素晴らしい記事 を参照してください。

スコープの問題については、Javascriptの通常の可視性ルール(関数の内部または外部で定義された変数、ローカル、グローバル、クロージャーなど)は、私が知る限り影響を受けません。

9
Alan

スクリプトタグの位置は重要です。関数をdocument要素にバインドする場合、関数を実装する前に、まずdocument要素をロードする必要があります。 getTeachers()がgetTeachers.jsファイルの関数であるとします。これはあなたにエラーを与えます:

<html xmlns="http://www.w3.org/1999/xhtml">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Unit Teachers</title>
<head>
 <script type="text/javascript" src="getTeachers.js"></script>
 <script type="text/javascript">
document.getElementById("buttonId").onclick=function(){getResults()};

</script>
 </head>
 <body>
 <form>
 <input type = "button" id="buttonId" value = "Press for Results"  /><br />
 </form>

<span id="results" /></span>
</body>
</html>

ヘッドが最初にロードされる前にエラーが発生し、指定されたIDの要素を見つけることができません。以下のコードは修正です:

<html xmlns="http://www.w3.org/1999/xhtml">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Unit Teachers</title>
<head>
 <script type="text/javascript" src="getTeachers.js"></script>

 </head>
 <body>
 <form>
 <input type = "button" id="buttonId" value = "Press for Results"  /><br />
 </form>
<script type="text/javascript">
document.getElementById("buttonId").onclick=function(){getResults()};

</script>
<span id="results" /></span>
</body>
</html>
4
Dhwaneel

そうではありません。ほとんどのプログラミングフレームワークは、ページ全体にスクリプトを分散させます。それが原因で問題が発生することはめったにありません(古いブラウザーからのみ)。

2
TheSmurf

Flexible, reliable and affordable cloud hosting

Sign up and get $50 bonus within 30-day!

Diodeusが言ったように、XMLHttpRequestを介してJavascriptをプルすると、おそらく機能しません。私の場合、エラーは発生しませんでした。ブラウザは新しいスクリプトを無視するだけです。

私はこれを使うことになりましたが、ひどくエレガントではありませんが、これまでのところ私にとってはうまくいきます:

http://zeta-puppis.com/2006/03/07/javascript-script-execution-in-innerhtml-the-revenge/

ExecJSの使用方法: http://zeta-puppis.com/2006/02/23/javascript-script-execution-in-innerhtml/

注:この行の_&lt;_に注意してください:for(var i=0;i<st.length; i++)

2
PJ Brunet

スクリプトがページのIDを参照し、ページがレンダリングされていない場合(つまり、スクリプトがHTMLの前にあるか、スクリプトがDOMの準備ができているのではなく、onloadで実行されている場合)もエラーが発生する可能性があります。

関数が呼び出される前にインラインスクリプト(関数の外)が配置されている場合、それらがまだ使用できない可能性があるため、エラーが発生する可能性があります。常に発生するわけではなく、ブラウザの種類やバージョンによって異なります。

1
Otávio Décio

JavaScriptのスコープルールはPerlに似ています-現在またはより高いスコープレベルで任意の関数を呼び出すことができます。唯一の制限は、関数を呼び出すときに関数を定義する必要があることです。ソース内の位置は関係ありません-時間内の位置のみが重要です。

ページの表示が遅くなるので、可能であれば<head>にスクリプトを配置しないでください(Alanが投稿したリンクを参照)。

1
user42092