イベント処理/JavaScript

JavaScriptでは、クリック等のイベント発生時に処理を実行させる事が出来ます。

本項では、イベント処理について説明します。

イベント

 マウスがクリックされた、実行ボタンが押された、キーが押された等の発生をイベントと呼びます。JavaScriptでは、イベントが発生した事を検知して処理をさせる事が出来ます。

 例えば、ボタンがクリックされるとアラートを出す事が出来ます。

イベントとハンドラ

 この時、呼び出される処理をハンドラと呼びます。

イベントハンドラ

 「フォームの使い方」で説明したonclick、onsubmit、onkeydown、onload等はイベントハンドラと呼ばれます。以下は、ボタンをクリックするとアラートが表示されるイベントハンドラの利用例です。

【イベントハンドラの使い方】
<form>
<button type="button" onclick="alert('表示');">数字が出ます</button>
</form>

 onclickにより、ボタンがクリックされた際にハンドラが呼び出され、alertが実行されます。

 関数宣言して呼び出す事も出来ます。

【ハンドラを関数で呼び出す】
<script>
function func1() {
    alert("表示");
}
</script>

<form>
<button type="button" onclick="func1();">数字が出ます</button>
</form>

 イベントハンドラはフォームの部品だけでなく、以下のように<div>や<image>等にも使えます。

【イベントハンドラをdivで利用した例】
<div onclick="alert('div内です');">
<image src="11.png" alt="スペードA" onclick="alert('スペードのAです');" />
</div>

 上記は、以下のように動作します。尚、分かり易いように枠を付けています。

スペードA

 枠内をクリックすると、「div内です」とアラートが表示されます。スペードのAをクリックすると、「スペードのAです」と共に「div内です」とアラート表示されます。2つのタグで囲まれた中でイベントが発生すると、子要素のハンドラだけでなく親要素のハンドラも動作します。これをイベント伝播と呼びます。

 1つのタグに対しては、同じイベントハンドラは使えません。

【1つのタグに同じイベントハンドラを設定した例】
<div>
<image src="11.png" alt="A" onclick="alert('1回目です');" onclick="alert('2回目です');" />
</div>

 上記はonclickが2つありますが、画像をクリックすると「1回目です」だけアラート表示されます。

イベントリスナー

 イベント処理の仕方として、イベントリスナーもあります。

【イベントリスナーの使い方(無名関数)】
<div id="div1">
<image src="11.png" alt="スペードA" id="image1" />
</div>

<script>
var x = document.getElementById("div1");
var y = document.getElementById("image1");
x.addEventListener("click", function(){alert("div内です");});
y.addEventListener("click", function(){alert("スペードのAです");});
</script>

 赤字部分でxからdiv1、yからimage1をオブジェクトとして参照しています。参照しているため、スクリプトは要素の下に記述する必要があります。青字部分は、クリックイベントが発生した時に関数を実行するよう記述しています。

 2つのイベントリスナーは、1行目でイベントを待つという処理を実行した後、2行目のイベントも待つという処理が行われます。つまり、2つのイベントは同時に待っている状態になります。このため、画像をクリックするとイベントハンドラの例と同じで、「スペードのAです」の後に「div内です」と表示されます。

 上記は無名関数で記述していますが、以下のように関数宣言して呼び出す事も出来ます。

【イベントリスナーの使い方(関数宣言)】
<div id="div1">
<image src="11.png" alt="スペードA" id="image1" />
</div>

<script>
function func1() {
    alert("div内です");
}
function func2() {
    alert("スペードのAです");
}

var x = document.getElementById("div1");
var y = document.getElementById("image1");
x.addEventListener("click", func1);
y.addEventListener("click", func2);
</script>

 赤字部分で関数func1とfunc2を呼び出しています。

 「スペードのAです」の後に「div内です」と表示されるように、内側から外側にイベントが実行される事をキャプチャリングと呼びます。

キャプチャリングとバブリング

 キャプチャリングはデフォルトの動作で、バブリングと言って外側から順番に実行する事も出来ます。バグリングにする場合、イベントリスナーの最後にtrueを指定します。

【バブリング】
<div id="div1">
<image src="11.png" alt="スペードA" id="image1" />
</div>

<script>
var x1 = document.getElementById("div1");
var y1 = document.getElementById("image1");
x1.addEventListener("click", function(){alert("div内です");}, true);
y1.addEventListener("click", function(){alert("スペードのAです");}, true);
</script>

 上記は、以下のように実行されます。

スペードA

 トランプをクリックすると、イベントハンドラの例とは逆で先に「div内です」が表示され、次に「スペードのAです」が表示されます。このように、キャプチャリングやバブリングによってイベントが伝播されます。

 又、イベントリスナーでは同じイベントに複数のリスナーが設定出来ます。

【イベントリスナーで同じイベントに2つのリスナーを設定した例】
<div>
<image src="11.png" alt="スペードA" id="image2" />
</div>

<script>
var y1 = document.getElementById("image2");
y1.addEventListener("click", function(){alert("1回目です");});
y1.addEventListener("click", function(){alert("2回目です");});
</script>

 上記は、画像をクリックすると「1回目です」の後に「2回目です」とアラート表示されます。イベントハンドラは、1つのタグに同じイベントハンドラを記述しても動作しませんが、イベントリスナーは同じイベントを記述しても動作します。

 このように、イベントリスナーはイベントハンドラより細かな制御が可能ですが、WindowsXPでサポートしているInternetExplorer8以前では動作しません。

イベント伝播停止

 イベントを伝播させたくない時は、event.stopPropagationメソッドを使います。

【event.stopPropagation利用例】
<div id="div3">
<image src="11.png" alt="スペード" id="image3" />
</div>

<script>
var z1 = document.getElementById("div3");
var z2 = document.getElementById("image3");
z1.addEventListener("click", function(){alert("div内です");});
z2.addEventListener("click", function(event){alert("スペードのAです");event.stopPropagation();});
</script>

 eventがイベント(クリックする)のオブジェクトです。event.stopPropagation()で伝播を停止します。

 実行例は、以下の通りです。

スペードA

 枠内をクリックすると、「div内です」と表示されます。画像をクリックすると、「スペードのAです」とアラート表示されますが、「div内です」とは表示されません。

 関数宣言して呼び出す時は、以下のようにします。

【関数宣言でイベントキャンセル】
<script>
function func1(event) {
    alert("スペードのAです");
    event.stopPropagation();
}

var z1 = document.getElementById("div3");
var z2 = document.getElementById("image3");
z1.addEventListener("click", function(){alert("div内です");});
z2.addEventListener("click", func1);
</script>

 赤字部分で引数を渡していませんが、青字部分では受け取っています。イベントオブジェクトは自動で引数として渡されるためです。

イベントのキャンセル

 イベントをキャンセルする時は、event.preventDefaultメソッドを使います。

【event.preventDefault利用例】
<form id="form2">
<input type="radio" name="radio1">選択1
<input type="radio" name="radio1" checked="checked">選択2
</form>

<script>
var z3 = document.getElementById("form2");
z3.addEventListener('click',function(event) {event.preventDefault();});
</script>

 ラジオボタンは、「選択2」にチェックが入った状態で表示されますが、それから変更出来ません。これは、イベントリスナーでクリックイベントの発生を検知した時、赤字のevent.preventDefault();によりクリックイベントをキャンセルしているためです。

 上記は、以下のように動作します。

選択1 選択2

 event.preventDefaultを利用すると、フォームで実行した時のページリロードへの対応も出来ます。以下は、関数宣言して呼び出すようにしています。

【event.preventDefaultを利用したページのリロードへの対応】
<form id="form3">
<input type="text" size="10">
<button type="submit">表示</button>
</form>

<script>
function func1(event) {
    event.preventDefault();
    alert("OK");
}

x =document.getElementById("form3");
x.addEventListener('submit',func1);
</script>

 「フォームの使い方」でテキストでエンターキーを押すとページをリロードするため、return falseを使ってリロードしないように出来ると説明しました。上記のように、event.preventDefaultを利用しても同じ事が可能です。

 赤字のsubmitは、実行イベントを示します。テキスト内でエンターキーが押されると実行イベントが発生し、func1が呼び出された後ページがリロードされますが、青字のevent.preventDefaultでキャンセルされます。

次のページコールバック関数

  • このエントリーをはてなブックマークに追加