2025年2月12日水曜日

addEventListener()の使い方

まず、一言説明
Q.「addEventListener」って何?
A.「クリック等のマウス操作や、キーボード操作、ブラウザリサイズ等操作で処理を発火できるようになる」


例えば、何かをクリックしたときに関数を呼ぶ場合
「<div onclick="setaf()">」とすれば対象の関数を発火できます。
1つ2つ程度なら全然これで良いと思います。

ですが…、数が多くなった場合はどうでしょうか100個200個divがあった時に全てonclickを入れたり操作するのは大変。
またはクリック以外でもブラウザ上で何か「こういう操作」が発生したらチェックするために関数を発火したい時に関数を発火できます。

経緯

とあるwebシミュレーターを作る時に、gridマップから何処をクリックしたか知りたいなぁという事がありました。
24x24マスのgrid=項目行列も含め625マスのdiv操作
その盤面から何処がクリックされたのか知りたい

操作領域は24x24。の領域を選択範囲19x19をセットで操作=361ヵ所
実際に操作処理するのが165ヵ所。

・・・面倒臭い。

使い方

対象要素.addEventListener( 種類, 関数, false )

一旦形だけ理解しましょう。
これをグローバルエリアに置きます。

第1引数:
固有の種類があります別途調べてください
(つまり、任意の名称設定できません決まったコマンド的なものです)

第2引数:
関数は自分で作った関数名を指定します

第3引数:
イベント伝搬方式のfalseは一旦そのままでいいです。

記述1

対象要素.addEventListener('click', abcdef, false);
function abcdef(){処理内容}

addEventListenerで指定する関数名には「()」は付けないで下さい
付けるとただの関数呼び出しになります
具体的にはリロードされただけで実行されます。

記述2:アロー関数

対象要素.addEventListener('click', () => {処理内容})

関数を呼ばずにすぐ処理したい場合この様に書きます
更に、記述1では括弧をつけないので引数が渡せませんが渡したい時は単にこの処理内容部分から普通に関数を呼べば良いです。

対象要素.addEventListener('click', () => {abcdef(引数)})
function abcdef(aaa){処理内容}

アロー関数の様な方法として無名関数というのもあって
対象要素.addEventListener('click', function() {処理内容}, false)

こんな感じでも記述できます
閑話休題

何処がクリックされたのか

話しを戻して、今回のやりたい事って何かというとつまるところ
「クリックしたgridにあるdivのどれが押されたか?」

ググってみたら「grid div 要素数える」とか色々検索したけどgrid.jsがとかライブラリjsでindexでとかArray.fromで要素を配列に変換したあとにArray.prototype.indexOf.call("集合の要素", "目的の要素")で数えるとか

・・・いやそんな面倒臭いはずは…だってまずforで要素探して数えてるiさえ関数に渡せればいいだけなのになぁとちょっと迷走

今回の実装方法

const target = document.getElementsByClassName('mybox'); 
for(let i = 0; i < target.length; i++) {
    target[i].addEventListener('click', ()=>{boxclick(i)});
}

クリックイベントを検知してそのカウンタiをただの関数に投げるだけ。
自分が求めていたのはこれだけなのに全然すっきりした答えが出て来なくて無駄な遠回りをした。
今回対象にしたのはClassNameです。
同じClass名を対象に丸ごと持ってそれを対象にクリックされたかを調べ発火
アロー関数先の関数に引数を渡してただ呼び出すだけ

記述位置

記述は操作する対象が存在してなければ実行できません
例えば、ヘッダーにいれたjsに書くと対象がロード前で実行失敗になります

つまりhtmlの一番下に書けばOKって事です
・・・ですが面倒臭いですよね

その場合はロードが完了後発火する所に記述すればいいわけです
一番手っ取り早いのは

window.onload=function(){ページロード後に実行したい関数()}

飛ばした関数の中に記述すればOK