動的に追加された要素もイベントを埋め込むニーズがあったのでそのメモ。
解釈としては「個別に要素にaddEventListenerしなくてもどの要素をクリックされたかがわかる」ということが実現できればいい。
最初から存在するdocumentオブジェクトにイベントリスナーを張っておけば、documentの上に乗っかってくる要素のイベントも拾ってくれますよ、というのが答え。
以下サンプルソース。
<html>
<button id="id1">id:1</button>
<button id="id2">id:2</button>
<a href="#">anchor1</a>
<script>
document.addEventListener('click', (e) => {
console.log(e.target);
})
</script>
</html>
実行結果
要素を左から順にクリックして最後に白い部分をクリックしたのが以下の実行結果。
こんな感じで、手前の要素がクリックされてることがわかる。あとは、idやクラス別に分岐を入れてもよし、独自の属性で分岐を作ってもよし。
ここから余談
別解としては、ドキュメントの要素を全部舐めて属性に応じたイベントリスナーを入れるという方法もあるけど、画面をロードするたびにそれが流れるのがヤダなぁと思って、ドキュメントだけにイベントリスナーを埋め込む方が軽いんじゃないかと思った。
昔の話。スマホのclickイベントは300ms遅くなるので「すべての要素を舐めてclickイベントがあったらタッチイベントに変えて反応を早くする」というJSライブラリがあったんだけど、むしろ最初のロードが遅くなってしまうという副作用があった。できるだけ初期化で流れる処理は軽くしておきたい。
ちなみにスマホのクリックイベントに遅延があるのはダブルタップのイベントがあるから一発目のタップではすぐに動かないようになってる。ダブルタップはスマホのズーム機能なのでダブルタップによるズーム機能を殺せばこの遅延はなくなる。
以下のメタタグでビューポートの幅がデバイスの幅と同じになるので、ダブルタップでは拡大されない。
<meta name="viewport" content="width=device-width">