パソコン工房の蔵出し・アウトレットパソコン

2008.02.07 改

このページについて
このページでは、初心者向けのjavascriptの実行方法について解説します。 スクリプトのhtmlへに記述はわかる、関数もわかる、if文程度の実行文も書ける、 ではどうやって使うの? と言う疑問が はじめてjavascriptに触れた時に思った疑問です。 あっという間に解けましたが(笑) その事もあって一応解説しておきます。


読み込みと同時

top
javascriptの実行文、関数の呼出し等をスクリプトタグ内に むき出しで書くと その実行文が読み込まれた時に実行されます。
<script language="javascript">
// var ステートメント実行
// documentオブジェクトの一部の値取得等
var $name = "artemis";
var $cookies = document.cookie;

// documentオブジェクトのメソッド
document.write("いらっしゃい");

// if文などの ステートメントの実行
// navigatorオブジェクトの操作
// historyオブジェクトの操作
if(navigator.userAgent.indexOf('MSIE') < 0 ){ history.back(); }

// windowの操作
window.alert("welcome"); // アラートボックスの表示
window.location.href = "./index2.html"; // このページへジャンプ

// fanctionステートメント 関数の定義がされるだけ
// 関数内の処理は実行されません
function dochange(){
    処理
}

//関数の呼出し
dochange();

</script>
変数の宣言などは むき出しで書く事で javascriptが読み込まれた時点で有効になります。 他の処理でこの変数を参照するよりも前に必ず宣言してください。

クッキー値も呼び出された時点で読み込みが可能です。

document.write();は基本的にこの方法でのみ使います。
document.write(変数や文字列)は この 変数の値や文字列をページに文字として表示させる為の物です htmlとjavascriptのみの基本構造では文字列などのコンテンツは書き換える事ができません。 従って、後から関数でこの docuement.write を使う事は基本的にありません。 document.write() こそ むき出しで書き込む必要がある典型的な物です。
注意:他のウィンドウの中身を丸ごと替える時には関数から使います。
またIE4から実装され始めたDOM操作では別の方法で、いつでも好きなようにHTML内のコンテンツを変更できます。 ですから、document.write()の必要性が減ってきてるとも言えます。

if文の様な構文も 読み込まれると同時に実行されます。 この if文での条件部分等で使われるプロパティや変数は、ここより先に読み込まれていないとエラーになります。

navigatorオブジェクトは javascriptが読み込まれる時点で操作可能です。 windowsオブジェクトとその下層 history、locationまでは普通に操作可能です。
frameやdocumentオブジェクトは、物によります。

問題は documentオブジェクトの下層や下層を指す配列プロパティなどです。 documentオブジェクトは基本的にhtmlが全て読み込まれた時点で document と言うオブジェクトが完成される為に、ドキュメント(html)のbodyが完全に読み込まれてからでないと 操作対象としては無効なものがあります。特に下層は、むき出しで書く実行命令に書くとエラーの元になります。
後で説明する、onload() (ロードされたらの意) と言うイベントハンドラがありますので、通常それを使います。


関数の呼び出しを読み込みと同時に行うのであれば、関数名(); と記述すると呼び出されます。 呼出しが行われた時点で、まだ関数が読み込まれていない、つまり関数より先に書くと エラーが出る恐れがあります。 また、この関数は 呼び出しがあった時点で実行されますので、この関数内の実行文に まだ読み込まれていない可能性のあるdocumentオブジェクト以下のオブジェクト操作があると エラーが出る可能性は大きいです。 通常、ページが読み込まれてから関数を呼び出すのであれば、イベントハンドラ( onload )を使います。

◆一般的によく使われるむき出しでの記述は
最初から値の決まっているグローバル変数の宣言
ブラウザ情報の取得関係
クッキーの取得
alert() 等でのこのページへの警告( 18未満はお断り 等)
条件によって ページをジャンプさせる(locationやhistory を使う)
document.write()による文字の表示

この様に、むき出しで書かない方が良い物や、むき出しで使うべき物 むき出しで使うと読み込まれた時点で実行されると言う即効性などを考慮して使います。

◆DOM時代の基本
DOM時代になってあらゆる要素をオブジェクトしてそうできるようになりました。
このあらゆる要素や、各要素の配列などは、ドキュメントが全て読み込まれた時点で初めて完成します。 つまり、なんらかのDOM処理が必要であれば、必ず読み込まれたのを確認してから操作するのが基本です。 自ウィンドウの場合はまず普通にこれが出来てると思いますが、フレームや子ウィンドウなどの操作をする時はこれが最も重要です。 大手の会社のHPでも、不明の変数、不明のサブウィンドウ、不明のiframe内のドキュメント操作などでエラーが出てることが良くあります。


イベントハンドラ

top
読み込み時に呼び出されない処理については ビジターの何らかの操作(イベント)がによって、その処理が呼び出されるようにできます。 ある操作(イベント)から手渡される呼び出しを可能にするのが javascriptのイベントハンドラと言う物です。
処理と書きましたが通常読み込み時に実行されないのは、関数として定義されている部分です。 しかしもう一つ、このイベントハンドラーに直接書き込んだステートメントは、イベントが発生するまでは 実行されません。
イベントハンドラーはいくつも種類がありますが個々のイベントについての説明は、とほほさんのリファレンスや Microsoft、Mozillaのリファレンスを参照してください。
<html>
<head>

<script type="javascript">
// グローバル変数 msieなら trueになります
$navi = (navigator.userAgent.indexOf('MSIE') >=0);

// イベントで呼び出される関数
function doevent( _n ){ alert( _n ); }

</script>

</head>
<body onload="doevent('load');">
↑ #1 onloadイベント

#2 onclickイベント
<a href="" onclick="doevent('click');">enter</a>

#3 onmouseoverイベント
<a href="javascript:;" onmouseover="doevent('over');">enter</a>

#4 onload イベント
<img src="" onload="doevent('load');">

#5 onmouseoverイベント ステートメント直書き
<a href="javascript:;"
onmouseover="if($navi){alert('msie')}">
browsercheck</a>

</body></html>
#1 は bodyタグに onloadをつけてjavascript関数を呼び出しています。 この場合 <body> 〜 </body> が完全に読み込まれた時点で ="ステートメント"; のステートメントを実行します。 つまりページ全体が読み込まれてと解釈してください。
ここでは関数を呼び出しています。 このbodyタグにつけた onloadで実行される場合は ページが読み込まれていますので、documentオブジェクト下層の 全てのオブジェクトが操作可能です。

#2 は アンカーに onclickをつけています。 onclickは付けたタグエリアがクリックされたら実行と言う意味です。 アンカーはクリックされると hrefの値へジャンプしますが onclickを付ける事でジャンプする直前にjavascriptを動作させる事ができます。

#3 は アンカーに onmouseoverを付けています。 onmouseoverはこれを付けたタグエリア上に マウスポインタが重なると、ステートメントを実行します。よくメニューの画像が変化したり ステータスバーに説明文字が表示されるのはこの様な方法でやっています。 ie4以上では imgタグなどにも付けられ、そのイベントオブジェクトをthis で引数として渡せますので リンク画像でなくても画像のすり替え等を簡単にできます。

#4 画像タグに onload を付けています。これはこの画像が完全に読み込まれたらステートメントを実行します。 画像が完全に読み込まれた時点と言うのはページが全て表示された状態とは限りません。 この画像がとても小さいサイズですぐ読み込まれるような場合は、ページが読み込まれるより先に動作する可能性もあります。

#5 これは#3で書いた onmouseoverと同じですが、ここでは関数を呼び出さずに ステートメントを直接書き込んでいます。しかも、スクリプトタグ内で定義されているグローバル変数 $naviを 利用しています。これが true なら if文のステートメントを実行します。 この様な使い方も可能であると言う例です。

この様に javascriptには イベントハンドラと言う物が用意されています。 どういうイベント(操作)から javascriptを起動させるのかを良く考えてプログラムを組めます。 DOM時代に入ってからは、全ての要素がオブジェクトですからそのオブジェクトに許される範囲で、どこにでもイベントを付けられます。 htmlファイル全体がjavascriptを起動する起動装置となり得ます。

イベントハンドラは
eventhandler = "ステートメント"; または eventhandler='ステートメント';
という形でタグに書き込まれます。 従ってステートメント内で、シングル、ダブルクォーテーションを使う場合は ステートメント全体を囲っている物では無い方の物を使うか \ をつけて 特殊文字として記述します。

イベントハンドラはインラインでタグに書き込まなくても、 そのタグをオブジェクトして定義して、そのオブジェクトにつける形で全てJavaScriptの中で済ませる事もできます。
<script type="text/javascript">
window.onload = function(){
document.getElementById('aaa').onclick = function(){ }
document.getElementById('bbb').onclick = function(){ }
}
</script>
例えばこんな感じで、ドキュメントが全て読み込まれた状態で、 ドキュメント内の要素をIDから指定してオブジェクトとして指定する。 そのオブジェクトにonclickというイベントをつけて、呼び出す関数まで定義する。
こんな方法にする事で、HTML内にイベントハンドラを一切つけないで済ませて、イベントを利用する事も可能です。
この他にも今は attachEvent()、addEventListener() というメソッドを使ってオブジェクトにイベントをつける事をJavaScriptからお粉九個ともできます。 詳しくは
=> イベント


アンカー

top
イベントハンドラ以外にもhtmlタグから javascriptを呼び出す方法があります。 それが アンカータグの href 属性にjavascriptを記述する方法です。
アンカータグは クリックされるとジャンプします。つまり元々クリックを受け入れる為の物です。 このアンカータグに onclickをつけてjavascriptだけを機能させたくても javascriptの動作の後に href="" 属性のジャンプを行います。 このアンカーの動作を無視させる為には
<a href="javascript:void(0)" onclick="関数;"></a>
<a href="javascript:;" onclick="関数;"></a>

href="#" を使うのは悪習慣ですのでやめましょう。
ここで既に出てきてしまいましたが、アンカータグのhref属性を使ってjavascriptを起動できます。
<script language="javascript">
$navi = (navigator.useragent.indexof('msie') >=0);
</script>
基本
<a href="javascript:ステートメント">start</a>
実動
<a href="javascript:alert('ok')">start</a>
<a href="javascript:if($navi){ alert('ok')}">start</a>
<a href="javascript:関数()">start</a>
href属性に javascript:(コロン) と書いて その後にステートメントを書きます。
ie4以上専用であれば、<span onclick="">start</span>と記述すればokですが netscape等も含め汎用なjavascriptを書くにはアンカーを使うのも一つの手でした。
今はめっきり不要になってきましたが、IEではIE6までCSSのhoverがアンカーにしか効かなかったので hoverを利用したい時には使っていました。 IE7はどのタグでもhoverを使えるので、もう不要ですね。
ちょっと余談:
これを言い換えると
アンカーで呼ぶページ名が javascript:関数() と言う事と同じ意味になります。
と言う事で、ブラウザのURLアドレスバーに javascript:alert('aaa') と入れてEnterしてみてください。 実行されますね?
つまりはそういうようにできているという事です。


フォーム

top
フォームでつかう。
これはあまり使わないかもしれませんが、フォームの actionからjavascriptを呼び出す方法があります。 フォームタグの action は フォーム内の submitボタンが押されると動作します。 このaction属性を使って、javascriptを起動する場合は、アンカーと同じく
<form action="javascript:ステートメント" method="post">
のように使います。フォームの各エレメントがjavascriptにデータとして送られるわけではないので 特に価値のある使い方は見つかりませんが、この様に使えるっていうだけです。 ちなみに method="post"を一応書いてください。無いと古いNetscapeでは動作しないと思います。
<form>
<input type="button" onclick="ステートメント">
でも同じようにjavascriptを呼べます。


時間差実行

top
本来 windowオブジェクトのメソッドとして解説すべき方法です。
javascriptには setTimeout() と言う タイマーメソッドがあります。
timerid = setTimeout("ステートメント",時間);
ステートメントは実行文、関数呼び出しなど、時間は 1/1000 秒単位。
この setTimeout() を むき出し記述や、イベントハンドラで使う事で 必要に応じて実行を遅らせる事ができます。
<script type="text/javascript">
function domes(){
    clearTimeout($dm);
    alert("こんにちは")
}
//#1
$dm = setTimeout("domes()",1000);
</script>
<body onload="setTimeout('domes()',500)">
#1 のように書くと読み込まれた時点から 1秒後に domes()が実行されます。 setTimeout()は一度しか実行されないので、必ず実行する場合等は setTimeout("domes()",1000); と記述するだけで $dmという変数に 代入する形にしなくても良いです。 明確に タイマー実行とタイマー切断 をする必要のある時は、このように タイマー用のidとして 変数に入れ、切断する必要のある場所で clearTimeout(変数) とします。

bodyタグの方でも同じようにdomesへ 0.5秒後の実行にしていますが これは、ページが読み込まれてから 0.5秒後です。 ここでは タイマーid を使っていませんが使ってもいいです。

setTimeout()では、ステートメント部分を シングルまたはダブルクォーテーションで囲ってください。 従って、ステートメント部分に記述した関数に引数を付ける時は逆のクォーテーションを使います。 これはイベントハンドラの場合は3重になるので \' を使ったりします。
複雑になって引数の受け渡しがうまく行かない場合は事前にグローバル変数の値を変更してから setTimeout()で関数を呼び出し、呼び出された関数側で、そのグローバル変数を参照するような方法をとってください。

◆再帰法と組み合わせて
setTimeout()は 時間差タイマーです。ただし1回しか実行できません。
そこで、関数の終りで、自分自身の関数を呼び出す再帰法と言う手法に setTimeout()を使って、一定時間毎に関数を実行させつづける事ができます。
var i = 0;
function doroop(){
    clearTimeout($dr);
    i++;
    alert(i)
    if(i<10){ $dr = setTimeout("doroop()",1000); }
}
この関数 doroop() は 一度呼び出されると i の値が 10 になるまでは alert(i) を1秒毎に実行します。 タイマーを使わない場合は 連続で10回 alert()が出ます。 再帰法を使う場合は、なるべく何かしらの条件で繰り返し(ループ)が終わるようにしておかないと 無限ループにおちいり、マシンがフリーズしたり、ブラウザが終了したりなどの 迷惑なエラーを起こします。

ついでにもう一つ例を
function dochange(){
    clearTimeout($dc);
    if(document.images[0].complete){
        document.images[0].src = "02.gif"
    }else{ $dc = setTimeout("dochange()",500); }
}
dochange();
	
これは、dochange(); と言う呼び出しが読み込まれると dochange() を実行します。 dochange()内では images[0] と言うイメージオブジェクト(画像)が完全に読み込まれているかチェックします。 読み込まれていれば document.images[0].complete は true と言う値を返すので、 document.images[0].src = "02.gif" で別の画像に取り替えています。
(Netscape系では読み込み完了ではなく、指定した時点でcomplete=trueを返す物も・・・) まだ、読み込みが終わってなければ、0.5秒後にもう一度呼び出し読み込みが完了しているかチェックします。 サイズの大きい画像があり、それが読み込まれてから何かしらのプログラムを動かしたい場合等にこれを使います。 この様に、便利な方歩もありますが、ie4、nn4 以上では setinterval() と言う一定時間毎に繰り返しをする タイマーが 別に用意されていますので、再帰法を使わなくても実現できます。
// setInterval()の例
function dochange(){
    if(document.images[0].complete){
        clearInterval($dc); // 条件が通ったら interval停止
        document.images[0].src = "02.gif"
    }
}
$navi = navigator.userAgent;
$version = $navi.charAt(8);
if($navi.indexOf('mozilla') >= 0 && $version >=4 ){
    $dc = setInterval("dochange()",500);
}
//備考:mozilla/4 以上なら 実行


その他

top
少し情報が古く、現在のテストを行っていません。
◆クロスフレーム − javascriptを起動する
フレーム構成の場合に他のフレームのファイルに記述されているjavascriptを操作できれば とっても便利なのですが基本的にこれはできませんでした。 で、今は?と言うとできます。
変数も関数も利用できます。ただ同じサイト内での話でクロスドメインなどは基本は無理です。

◆クロスフレーム − javascriptと変数(値)の共有
他のウィンドウにあるjavascriptと変数を共有する事ができなかった時代の話。
共有するには方法としては2つありました。
まず、フォームを操作できる事を利用して、フォームに変数の値を書き込みます。 各ページのjavascriptから、そのフォームの値を読み込んだり書き換える事で 値の共有と言う事が可能になります。 しかし、フォームを読み書きする時に、必ずフォームのあるページ全体が読み込まれていないとエラーが出ますし、 ロードタイミングで操作する場合エラーの危険が伴います。 このロードタイミングでの話は、今も同じです。 先方の操作対象やJavaScriptが読み込まれていないと、それを利用する事はできません。
IE4以上には readystateと言う ドキュメントの読み込みが完了しているかどうかをチェックする プロパティがありますので エラー回避はできますが Netscape系はFireFoxになってもHTMLドキュメントに対しては実装されていないようですね。
こういった場合は、操作される側のJavaScriptでonload で tureになる変数を用意しておく事で、 『その変数がもしあれば?そしてtrueなら?』と言う確認方法でロード完了を把握する事ができます。

もう一つの共有方法は、クッキーを使う方法です。クッキーの仕組みを理解していないと使えませんが 一時的にクッキーに値を格納させて別ページでこれを読み取ると言う方法です。 この場合は、ページを移動しても移動先のページで値が取れるので、クロスフレームだけではなく ページ移動でも変数を維持し続ける事ができるという便利な方法でもあります。 まぁ、所詮変数であって消えてしまったページのオブジェクトを持ち越すことはできませんが、 文字列にして持ち越すことは可能です。
IE4は当時からスクリプトレット技術でパブリック変数と言う物を使って 他のページから変数の値を変更させたりする事が可能になっていたので便利でした。

◆クロスフレーム − ドメイン
フレーム構成でそれぞれのフレームのファイルのドメイン名が違う場合です。 セキュリティ上、他人のページを表示させてそれを操作できる事になってしまいますので 新しいブラウザの方が制限が厳しくなっています。 古いブラウザではできちゃったりもしますが、自分だけができても何の価値もありません・・・(^^;

◆VBScriptとの 関数・変数 の共有
VBScriptは IEで使用可能なスクリプト言語です。とくにie4以上ではかなり便利です。 VBScriptとjavascript(JScript)間での 関数や変数の共有は基本的にできたはずです。
今は使わなくなったので、どうなってるか・・・ですが、 IEだけに有用なスクリプトを書く場合はVBScriptで書いてしまえば何も気にしなくて済むかも?

さて、最初に書いた時代からかなり年月が経ち2008年になっています。 もう今の時代ではJavaScriptでクロスフレームさせたり、値の共有などをする必要がほとんどなくなりました。
と言うのもサーバーサイドスクリプトで非常に便利で扱いやすいPHPがあたりまえに使えるようになってきている事で、 クッキーを利用せずともデータを保持できるセッション管理が容易にできるので JavaScriptであれこれ無理な方法を使わなくても済んでしまいます。 また、双方のセキュリティ面(ユーザー側の防衛、サーバー側の防衛)からもJavaScriptは、無作為に使う事は敬遠されがちになっています。 JavaScriptやDHTMLが進化すればかなり面白いことも出来たと思うのですが、 セキュリティの面、時代の流れと現在のホームページの必要性や有用性などの方向がかなり変わってきた事で JavaScriptはそれほど大きな役割を果たせなくなってしまったようです。 が、ファイルを読み込んだりできるようになったり、オブジェクト指向が進んだ事で、 少し違う方向性を持ちながら変化しつつあります。

どんなに良くなってもJavaScriptは所詮クライアントサイドスクリプトである事は忘れないでください。
つまり便利な方法が生まれてもセキュリティに問題を起こすような場合は制限がかかる可能性がある。 また、ビジターがJavaScriptを無効にしたらそのプログラムは全て無効になると言う事です。

ビジター側が『是非利用したい』と言うサイトで信用されているサイトであれば、 『JavaScriptを必ずONにしてください』と言う制限を書けることができます。
でも、一般のホームページで何をされるかわからない相手では『必ずON』といわれても『じゃぁ他所に行く』って事にもなりかねません。 そういう意味では、JavaScriptは色々な縛りがあると言う面は諦めるしかない面でもあります。


←前 次→



専用ページから申し込むと
So-netより高い3万円CB

案ずるより産むが易し
使ってみれば疑問も解決

XREA+ (plus) 206円/月
( お試し7日間 )

CORE SERVER 428円/月
( お試し15日間 )

ロリポップ 270円/月
( お試し期間10日間 )

ヘテムル 1620円/月
( お試し期間15日間 )

さくら 129円/月
( お試し期間2週間 )

無駄な高額ドメイン管理料金払ってませんか?

バリュードメイン
ムームードメイン