Javascriptのイベント登録に於けるイベントハンドラとaddEventListenerの使い分け

9月も終わりに近付き猛暑だった日が懐かしく感じる季節となりました。

さて、今回は Javascript でイベント処理をさせる時に使う「イベントハンドラ」(要素セレクタ.on****) と「addEventListner関数」の使い分けについてです。
どちらもイベントを同じように登録できますが、微妙に違うところがあります。


イベントハンドラとは?

イベントハンドラは、ブラウザ上で発生したイベントをトリガにある命令を呼び出すことができるものです。
良く使うものには、クリックを検出する “onclick” や読込完了を検出する “onload” などがあります。

イベントハンドラは要素の属性として書くこともできるので、ちょっとした処理を追加するだけなら要素タグ内で完結させることもできます。

ハンドラの例として、以下のコードを実行するとクリックに応じてアラートが表示されます。

<button onClick="alert('クリックされました!')">クリックして下さい</button>

Javascript コード内から呼び出す場合には、セレクタにより要素を指定して “要素セレクタ.on**** = Function;” とイベントを登録することができます。

<Javascript>
document.getElementById("test1").onchange = function(){
  alert("内容が「" + this.value + "」に変更されました!");
};

<HTML>
<label for="test1">内容 : </label><input id="test1" value="変更して下さい">


イベントリスナaddEventListner関数とは?

イベントハンドラと似た (場合によっては同列とみなす時もある) 動きをするメソッドに “addEventListner 関数” があります。
こちらもブラウザ上でのイベントをトリガに処理を実行させるように働きます。

こちらの関数の書式は、以下の通りです。

要素セレクタ.addEventListner("イベント", Function, キャプチャオプション);

第1引数にはトリガとなるイベント名を渡します。
イベント名はイベントハンドラの “on” を除いたものが主に使われます。

ここで、便利なイベントトリガがあります。
それが「DOMContentLoaded」というイベント名になるものです。

これを指定すると画像などの読込を待たずに DOM ツリーの読込が終わった瞬間にイベントが発生します。
すると、DOM ツリーの操作だけを行う処理を、onload のように画像の読込を待たずに高速に実行させることができます。便利ですね!

第2引数には実行させる関数を指定します。
多くは無名関数 function(){ /* 実際の処理 */ } が使われます。

最後のキャプチャオプションには、基本的には true/false の真理値が使われます。
初期値は false です。

true と false で何が異なるかは以下のページが非常に分かりやすいので、参考にしてみて下さい。
特に意識しない場合は初期値の false で何ら問題はないと思います。

・so-zou.jpさん – JavaScript プログラミング解説>イベントフロー (event flow)

最近では、スクロールイベントでの動作遅延を回避するオプション {capture : true/false} もあるのでややこしいですが、そこまで気にしなくてもとりあえずOKです。

先ほどのイベントハンドラの例と同じ動作を addEventListener 関数で書いてみましょう。

<Javascript>
document.getElementById("test2").addEventListener("click", function(){
  alert('クリックされました!');
}, false);

<HTML>
<button id="test2">クリックして下さい</button>


<Javascript>
document.getElementById("test3").addEventListener("change", function(){
  alert("内容が「" + this.value + "」に変更されました!");
}, false);

<HTML>
<label for="test3">内容 : </label><input id="test3" value="変更して下さい">


イベントハンドラとaddEventListner関数の違いと使い分け

では、ようやく本題です。

ここまで見てきてどうもどちらの方法も同じようなことができることがわかりました。
では、この二つの違いは何でしょうか?

それは、イベントハンドラはイベント発生時に一つの処理しか登録できませんが、addEventListener 関数は一つのイベントにいくつもの処理を追加していくことができます。

イベントハンドラでは複数の処理を行う場合、呼び出す関数内から更に呼び出すか複数の処理をまとめておく必要があります。
元々処理させたい内容が全て揃っている場合は良いですが、動的にイベントを追加していきたいような場合はちょっと面倒です。

そんな場合は addEventListener 関数を使うと簡単に複数の処理を追加していくことができ便利です。

じゃあ、全部 addEventListener 関数でいいじゃん?って思いますよね。
イベントハンドラを使う理由はそうないように感じますが、以下の場合はイベントハンドラが有利です。

【イベントハンドラ】デフォルトのイベント処理を別の処理で置き換える場合

あるイベント処理に対してデフォルトの処理がある場合にその処理を削除して別の処理で置き替えたいことがあります。

良くあるのがアンカー (<a> タグ) に対して、通常のページ遷移に変わって違う動作を割り当てたい場合です。
これを addEventListener 関数で書いてしまうとデフォルトのページ遷移がキャンセルされずに実行されてしまいます。
(古いブラウザに対応するには一工夫必要ですが対応する方法もあります、後述します)

また、同様に既に登録したイベント処理を上書きしたい場合にもイベントハンドラが楽です。
addEventListner 関数で登録したイベント処理は removeEventListener 関数で削除できますが、無名関数は消せないので注意が必要です。

例えば、ギャラリーサイトでアンカーに対して拡大表示の関数を割り当てて、通常のページ遷移は無視するようにしています。

具体的には onclick ハンドラの関数の返り値に真偽値の “false” を返すことでデフォルトのページ遷移を中止することができます。
アンカータグの場合は、href 属性に “javascript:” から始めた方法で書けば “false” を返す必要はありません。

href 属性にアドレスを指定している場合は、右クリックのコンテキストメニューに通常のアンカーと同様の表示になります。
“スクロールボタン” や対応ブラウザでは、”右クリックしながら下ドラッグ” で新規タブで開くこともできます。

<href属性の値が不要な場合>
<a href="javascript:(function(){alert('クリックされました!');})();">クリックして下さい</a>

<イベントハンドラに登録する場合>
<a href="https://analogstd.com/" id="test4">クリックして下さい</a>
<script>
document.getElementById("test4").onclick = function(){
  alert("クリックされました!");
  return false;
};
</script>

<href属性の値が不要な場合>
クリックして下さい

<イベントハンドラに登録する場合>
クリックして下さい

【addEventListener関数】デフォルトのイベント処理をキャンセルする場合

実は addEventListener 関数でもデフォルト処理の削除は可能です。

それには preventDefault 関数を使います。
とりあえずサンプルコードを見て下さい。

<preventDefaultを使う場合>
<a href="https://analogstd.com/" id="test5">クリックして下さい</a>
<script>
document.getElementById("test5").addEventListener("click", function($e){
  alert("クリックされました!");
  $e.preventDefault();
}, false);
</script>

クリックして下さい

preventDefaut 関数は受け取ったイベントに設定することでブラウザのデフォルト処理をキャンセルしてくれる便利な関数です。

但し、古い IE (IE8 以前) には対応していないので、少し工夫が必要です。
preventDefault 関数をサポートしていない場合に “false” を返してあげるとうまくいきます。

<IE8以前にも対応させる場合>
<a href="https://analogstd.com/" id="test6">クリックして下さい</a>
<script>
document.getElementById("test6").addEventListener("click", function($e){
  alert("クリックされました!");
  ($e.preventDefault) ? $e.preventDefault() : $e.returnValue = false;
}, false);
</script>

クリックして下さい

まとめ

以上、Javascript に於けるイベント処理についてでした。

柔軟な対応ができる addEventListner 関数ですが、比較的新しい関数なので使い方が少し複雑になっています。
簡単なイベント処理ならイベントハンドラを使ってしまった方が楽だと思います。

どんな処理にしたいかを考えてより簡単で分かりやすい方を使うようにしていけば良いでしょう。
色々な使い方をしっておくことが大切ですね。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)