素のJavascriptの進化に伴い、脱jQueyの動きが盛んですが、jQueryに慣れすぎていてると「あれ、これJavascriptでどう書くんだっけ」となることがあると思います。
この記事では、素のJavascriptで複数要素にイベントを登録する方法と複数のイベントを登録する方法、そしてそれを組み合わせて複数要素に複数イベントを登録する方法について記します。
やりたいこと
複数要素に複数イベントを登録したい場合、例えばhogeクラスとfooクラスにclickイベントとmouseoverイベントを登録したい場合、jQueryであれば下記のように書けば実現できます。
$(document).on('click mouseover', '.hoge, .foo', (e) => {
console.log(e.target)
})
しかし、これをJavascriptに置き換えようとして直感的に下記のように書いても動きません。
document.querySelectorAll('.hoge, .foo').addEventListener('click mouseover', (e) => {
console.log(e.target)
})
上記のコードが動かない理由は以下の二点です。
・querySelectorAllの結果にaddEventListenerは使えない
・addEventListenerは複数のイベントを登録できない
そのため私たちは以下の二つのことを学ぶ必要があります。
・複数要素にイベントを登録する方法
・複数のイベントを登録する方法
上記2点を学び、最終的には以下のような形でイベント登録できる関数の作成を目指します。
registerEvent('click mouseover', '.hoge, .foo', (e) => {
console.log(e.target)
})
複数の要素にイベントを登録する方法
素のJavascriptで複数の要素にイベントを登録しようとする時、直感的に以下のようなコードで動きそうな気がしてしまいますが、これはうまく動きません。
上の方でも説明しましたが、querySelectorAllの結果にaddEventListenerは使えないのです。
NG例:
document.querySelectorAll('.hoge, .foo').addEventListener('click', (e)=>{
console.log(e.target)
})
querySelectorAllの結果をループで回し、各要素にaddEventListenerを適用するとうまく動きます。
OK例:
document.querySelectorAll('.hoge, .foo').forEach((element) => {
element.addEventListener('click', (e) => {
console.log(e.target)
})
})
複数のイベントを登録する方法
素のJavascriptで複数のイベントを登録しようとする時、直感的に以下のようなコードで動きそうな気がしてしまいますが、これまたうまく動きません。
最初の方でも説明しましたが、addEventListenerは複数のイベントを登録できないのです。
NG例:
document.querySelector('#hoge').addEventListener('click mouseover', (e)=>{
console.log(e.target)
})
イベントを空白で分割してループを回し、各イベントをaddEventListenerで適用するとうまく動きます。
OK例:
'click mouseover'.split(' ').forEach((event)=>{
document.querySelector('#hoge').addEventListener(event, (e)=>{
console.log(e.target)
})
})
複数要素に複数イベントを登録する方法
さて、ここまででわたしたちは複数要素にイベントを登録する方法と複数のイベントを登録する方法を学びました。これらを組み合わせて複数要素に複数イベントを登録する方法を見てみましょう。
document.querySelectorAll('.hoge, .foo').forEach((element) => {
'click mouseover'.split(' ').forEach((event)=>{
element.addEventListener(event, (e)=>{
console.log(e.target)
})
})
})
うーん、実現はできましたが冗長ですね。最後にこれを関数化してみましょう。
イベント登録を簡単にする関数を作成する
ここまでで、複数要素に複数イベントを登録することはできましたが、記述が冗長になってしまいました。関数化して素のJavascriptでのイベント登録を簡単にしましょう。
function registerEvent(events, selector, callBack) {
document.querySelectorAll(selector).forEach((element) => {
events.split(' ').forEach((event)=>{
element.addEventListener(event, (e)=>{ callBack(e) })
})
})
}
この関数を共通ファイルに入れておくことで、どこででも簡単にイベント登録を行えるようになります。
上記関数を使用してイベント登録を行うには以下のように記述します。
registerEvent('click mouseover', '.hoge, .foo', (e) => {
console.log(e.target)
})
以上、素のJavascriptで複数要素に複数イベントを登録する方法でした。