プログラムを書く場所を分類すると、次の4種類になるでしょう。 ここでは、これまで紹介していない書き方や 注意を含めた 書き方のまとめを示します。
【1】 | これまでの方法で、scriptタグ内に記述 |
関数の作成、変数用意、命令実行表現を書きます。 実は以下に示すようにheadだけではなく、body内にも書くことができます。 |
【2】 | HTMLとは別の外部ファイルに記述 |
<script type="text/javascript" src="ファイル名.js"></script>で、それを、その位置に取り込む。
|
【3】 | onclickなどのイベント駆動処理部に記述 | 命令実行表現を書くことができます。 |
【4】 | aタグ内のリンク部に記述 | <a href="JavaScript:この部分に書く"> |
一般に関数(つまり function )は、上記表の【1】または、【2】の所で作ります。
ですが、関数は 作っただけでは実行しません。よのような規則になっているのです。
作ったfunctionという命令を実行させる表現が、関数名()で、
それをonclinkなどのイベントで呼び出しする【3】の手法が最も多いでしょう。
クリックした時に実行させる例:onclick="関数名()"
ですが 上記の表で示した通り、実行させる表現は4通あります。
つまり、【1】または、【2】の所では、
関数を作る記述以外に、作った関数などを実行させる記述もできるわけです。
(以前に紹介した変数の代入例)
実行させる記述は、functionの外側にある記述です。
この部分は、
HTMLを表示する前にブラウザのHTMLの内容を上から下の順に解析しながら実行します。
その例を以下に示します。
これはHTML表示直前で、0〜1.0のバラバラな数値を作って変数vに記憶した後、
そのvの評価のifで場合分けし、XXの名前付いたimgの画像を変更しています。
なお画像をクリックすることで、vの内容をalertで出す関数を実行させていますが、
この関数は画像をクリックしなければ実行しません。
で確認できます。
バラバラな数から画像を選択しているので、表示ごとに異なる画像が出るでしょう。これを何回か押して確認してください。
<html lang="ja"><head><title>test</title></head> <body> <img name="XX" onclick="sub()"> <script type="text/javascript"><!-- var v; function sub(){ alert(v); } v=Math.random()//0〜1.0のバラバラの数値を得る if(v <= 0.33) document.XX.src="img/faceA0.gif"; else if(v <= 0.66) document.XX.src="img/faceA1.gif"; else document.XX.src="img/faceA2.gif"; // --></script> </body></html>
上記【1】で示した例と、全く同じように動作するもので説明します。 以下は単に<script>の部分を別の外部ファイルに移動した例です
var v; function sub(){ alert(v); } v=Math.random()//0〜1.0のバラバラの数値を得る if(v <= 0.33) document.XX.src="img/faceA0.gif"; else if(v <= 0.66) document.XX.src="img/faceA1.gif"; else document.XX.src="img/faceA2.gif";
上記のファイルをabc.jsの名前で用意したとします。その場合に これを利用するHTMLは 次のようになります。
<html lang="ja"><head><title>test</title></head> <body> <img name="XX" onclick="sub()"> <script type="text/javascript" src="abc.js"></script> // --></script> </body></html>
【1】の間違い例を以下に示します。エラーはdocument.XX.src
の部分です。
この表現は、XXの名前のimgが存在していなければ使えません。
functionの外側であるこの部分は、
HTMLを表示する前に HTMLを解析しながら実行するのですが、
<img name="XX" onclick="sub()">の部分が
実行するこの部分より前に解析されていないと、未解析と判断されて
「存在しない」というエラーになってしまいます。
よって、<img name="XX" onclick="sub()">が
imgタグのname属性を使う前の位置に、
書いてあれば、上記先頭の例のように正しく動作できるわけです。
<html lang="ja"><head><title>test</title></head> <body> <script type="text/javascript"><!-- var v; function sub(){ alert(v); } v=Math.random()//0〜1.0のバラバラの数値を得る if(v <= 0.33) document.XX.src="img/faceA0.gif"; else if(v <= 0.66) document.XX.src="img/faceA1.gif"; else document.XX.src="img/faceA2.gif"; // --></script> <img name="XX" onclick="sub()"><!-- ←この位置でなく、上の の位置にあれば動作可能 --> </body></html>
この不具合の実行は で確認できます。
functionの内側で用意した変数は、そのfunction専用の変数で、
そのfunctionが実行した時に作られて、functionの動作が終わった時に無くなる変数です。
(これはローカル変数と呼ばれます)
対して functionの外側で用意した変数は、HTMLを表示する前に HTMLを解析しながら
用意され、ブラウザ表示が別ページに移動するか または閉じられるまで記憶内容を保持する変数です。
これはグローバル変数と呼ばれることがあります。
この違いにより、過去に作成した例で、変数の用意する位置を変更すると正しく動作しないものが
あります。
以下で 変数の設定する記述位置によって、動作する例としない例を示します。
<html lang="ja"><head><title>test</title></head>
<body>
<script type="text/javascript"><!--
function sub(){
var obj=document.XX;//XXの名前のimgタグのオブジェクトを変数に記憶
obj.src="img/faceA1.gif";
}
// --></script>
<img name="XX" src="img/faceA0.gif" onclick="sub()">←クリックで変更
</body></html>
上記は正しく動作します。
で確認できます。
しかし下記は、動作しません。→
で不具合を確認できます。
<html lang="ja"><head><title>test</title></head>
<body>
<script type="text/javascript"><!--
var obj=document.XX;//XXの名前のimgタグのオブジェクトを変数に記憶
function sub(){
obj.src="img/faceA1.gif";
}
// --></script>
<img name="XX" src="img/faceA0.gif" onclick="sub()"><!-- ←ここで名前を付けている -->
</body></html>
上記var obj=document.XX;の部分が、
XXの名前を付ける記述の前にあるため、objに 無いという意味のデータnullが記憶されます。
よって、実行時にnullの存在しないオブジェクトに対する操作が失敗します。
(imgのタグ位置をscriptタグの前に移動することで、動作可能になります)
対して、function内のvar obj=document.XX;は、クリック操作で実行します。
その時点では、XXの名前のimgが既に存在して見えているので、そのオブジェクト取得できて それを変数に管理できます。
つまり、
注意すべきは、スクリプトが実行するタイミングです。
(過去にも
エラーが生じる例の参考を説明しています。)
なお、
グローバル変数では重複した名前をつけられませんが、ローカル変数は使える
範囲以外の変数と重複して名前を付けてもよいことになっています。
つまりfunc1とfunc2のfunctionの中のそれぞれでvar i;と宣言して
同じ名前の i を用意しても構わないということです。(参考:名前の付け方)
なお、正確に言うなら、「関数内のローカル変数は、全て関数の先頭で宣言されたことになる」
規則になっています。(CやJava言語における、ブロックスコープという概念はありません。)
<script type="text/javascript"><!-- --></script> の表現は、複数の箇所で使うことができます。 また、document.write(文字列)は、HTMLを表示する前の HTMLを解析しながら実行するタイミングで使うと、 その箇所へ文字列を埋め込むような使い方ができます。以下にその例を示します。
<html lang="ja"><head><title>test</title></head> <body> <script type="text/javascript"><!-- function sub(){ var s='<a href="ex/n7003.htm">HTMLで使う単位</a><br>'; s+='<a href="ex/n8001.htm">HTMLで使う色名</a><br>'; document.write(s); } // --></script> <p>以下にリンクを示します</p> <script type="text/javascript"><!-- sub();//ここで、functionを実行させている。 // --></script> </body></html>
上記は正しく動作します。
で確認できます。
しかし下記は、動作しません。→
で不具合を確認できます。
<html lang="ja"><head><title>test</title></head> <body> <p>以下にリンクを示します</p> <script type="text/javascript"><!-- sub();//ここで、functionを実行させている。 // --></script> <script type="text/javascript"><!-- function sub(){ var s='<a href="ex/n7003.htm">HTMLで使う単位</a><br>'; s+='<a href="ex/n8001.htm">HTMLで使う色名</a><br>'; document.write(s); } // --></script> </body></html>
関数の呼び出し前に、
関数が作られていなければならない規則があります。
そうでないと実行エラーになります。
上記の不具合の場合、関数呼び出し記述のsub();が、
ブラウザの初期表示とともに実行する位置にあります。
よって まだブラウザの表示に関わるHTML全体の構造を読み取っていない段階での実行であり、
しかも関数定義(関数を作る記述)が後方にあるので、
見つからないエラーになるのです。
つまり正しく動作する例のように、関数定義(関数を作る記述)が
関数呼び出し記述のsub();の位置より前に
あれば良いということです。
これは、外部の別ファイルに書いた記述の【2】の手法の場合にも、同じ注意が必要です。
この表現は、これまでたくさん練習しました。
ここに書ける表現は、関数呼び出し以外の命令表現も可能です。
次の例では、idがabcの名前の部分へ 0から1.0のバラバラ値に変更するボタンのonclickで
次のように書くことができます。
<div class="S" style="background-color: #CCCCCC;"> <b><span id="abc">0.51234</span></b>の値<br> この<input type="button"value="ぼたん" onclick="document.getElementById('abc').innerHTML=Math.random()"> をクリックで、上記を値を変更します。 </div>
上記ソース部分は、次ように表示されます。
個人的には、この表現を使いません。以前にボタン以外でonclickを書けないブラウザがあって、
それに対応するために、この表現を使った経緯があります。
上記【3】と同じ動作を行う例を、参考として以下に示します
<a href="JavaScript:命令を書く">
〜</a>の書き方ですが、
命令を書くの部分で書いた実行の結果が、「ある値」を表現する場合に
その値のページに移動することになります。上記例ではそれを防ぐために、
最終的にデータの結果が無いvoid(0)という表現を使っています。
<div class="S" style="background-color: #CCCCCC;">
<b><span id="abc2">0.51234</span></b>の値<br>
この<a href="JavaScript:document.getElementById('abc2').innerHTML=Math.random();void(0)">
部分</a>
をクリックで、上記を値を変更します。
</div>
上記ソース部分は、次ように表示されます。