イベントハンドラとイベントリスナ
- イベントに対する処理自体をイベントハンドラまたはイベントリスナと呼ぶ。
- イベントハンドラは一つの要素、一つのイベントに対して一つしか設定できない。
- イベントリスナは複数設定できる。
- イベントに対する処理の設定方法は以下の通り。
- HTML要素の属性を指定する(イベントハンドラ)
- DOM要素のプロパティを指定する(イベントハンドラ)
- EventTarget.addEventListener()を利用する(イベントリスナ)
HTML要素の属性を指定する
<input id="foo" type="button" value="foo" onclick="alert('bar')">
ただしHTMLとJavaScriptを混在させると、可読性が低いので、通常はJavaScript のファイルは一つにまとめる。
DOM要素のプロパティを指定する
<script>
var btn = document.getElementById('foo');
function sayFoo(){
alert('foo');
}
btn.onclick = sayFoo;
//正 :関数自体(sayFoo)を設定する
//誤り:button.onclick = sayFoo();だと関数実行した返り値設定することになるので誤り
</script>
<input id="foo" type="button" value="foo" onclick="sayFoo()">
EventTarget.addEventListener()
- addEventListener()メソッドを使うと、特定の要素の特定のイベントに対して複数のイベントリスナを設定できる。
- 新しいDOMプロパティは既存のものを上書きする。
- 第3引数でキャプチャリングフェーズとバブリングフェーズを指定できる。
- DOM Level3では、第3引数を省略した場合にバブリングフェーズで実行される。
- DOM Level3では、イベントリスナの実行順序は登録順で実行されると定義されている。
<script>
btn.addEventListener('click' sayHello,false)
btn.addEventListener('click' sayHello,false)// 前のイベントリスナを上書きします
// ...
btn.addEventListener('click' sayHello, true)// フェーズが異なれば別のものとして登録される
</script>
イベントの伝播
- イベントは以下の3つのフェーズに分かれて処理される。
- キャプチャリングフェーズ
- ターゲットフェーズ
- バブリングフェーズ
キャプチャリングフェーズ
Windowオブジェクトからはじまり、DOMツリーを下に辿りイベントが伝播していくフェーズ。
ターゲットフェーズ
イベントターゲットに登録されているイベントリスナが実行されるフェーズ。
バブリングフェーズ
イベントターゲットからDOMツリーを上に辿りイベントが伝播していくフェーズ。
標準処理のキャンセル
- ブラウザが標準的に実装している処理を実行させないようにすることができる。
- Event.preventDefault()メソッドを使う。
- 例えばa要素をクリックすると、そのリンク先のページに遷移するが、preventDefault()メソッドを実行すると その動作が実行されなくなる。
- イベント中にpreventDefault()メソッドで中止できないイベントもある。
- イベントハンドラでfalseを返すのと同じ。
<a href="/" onclick="return false">Click here</a>
or
<a href="/" onclick="event.preventDefault()">here</a>
参考
EventTarget.addEventListener() - MDN Web docs
JAVASCRIPT.INFO - ブラウザイベントの紹介