JavaScript: イベント処理 (1)
table タグの各 td タグにイベント処理を付ける例でいろいろ。tableタグ: JavaScript サンプル
td タグに直接 onclick="関数名()" を入れる
初歩的なサンプルでよく使います。 td タグ内に直接 onclick="関数名()" を記述して関数を呼び出します。
<td onclick="関数名(引数)"> 例: <td onclick="onclickTd(123, '文字列1');"> //ユーザー指定の引数。 <td onclick="onclickTd(this);"> //this は td になる。 <td onclick="onclickTd(event);"> //マウスイベントを引数にする。TestJS_event_table_td01.html
関数の引数いろいろ。
TestJS_event_table_td02.html
td 内に別の要素(p や spanなど)があるときのイベントの発生の仕方など。
上の記述方法では不都合な場合も出てきます。例えば td タグでは
- 多くの td がある table で個別に onlick=...
を書くのは面倒です。
繰り返し同じ記述が出てきます。 JavaScript で一括登録の処理にしたい場合もあります。 - table 自体を JavaScript で作成する場合は上の方法が使えません。
HTML にはじめから table タグや td タグが存在していない場合は 上のような記述ができません。
ということで、td に onclick= をつける処理も JavaScript 化します。下に続く。
JavaScript で td にイベント処理をつける
1) 元のサンプル
最初に元のサンプルです。
TestJS_event_table_td11.htmltable の セル(td) をクリックすると色が変わるサンプル。
上のサンプルは table の各 td に onclick="onclickTd(this)"
という記述が繰り返し出てきます。
<tr> <td onclick="onclickTd(this)">0-0</td> <td onclick="onclickTd(this)">0-1</td> ...
次にイベントを付ける処理も JavaScript でまとめてみます。
2) onclick を付ける処理を JavaScript でまとめる
- TestJS_event_table_ES2015.html
ES2015 のサンプル。IE11 では動作しません。
function initTable(){ //table 内の td 要素をすべて取り出す。 const list = document.querySelectorAll("#TABLE1 td"); //td にクリックイベントを付ける。 for (const td of list){ td.onclick = event => onclickTd(td, event); // => はアロー関数です。 } }
- TestJS_table_td_click02.html
table td にイベント処理を付ける。
関数をオブジェクト App = {}; にまとめたサンプル。 - TestJS_ul_li_tree02.html
ul,li ツリー表示のサンプル。 ツリーの要素にクリックイベントを付け、 フォルダーを開いたり閉じたりする。
ul,liタグ, JavaScript, ツリービューのサンプル
IE11 時代までの昔話いろいろ
(2021) こちらは参考程度の昔話です。 昔は面倒な話がいろいろありました。 IE を気にしない人は眺める必要ありません。
サンプル:TestJS_event_table_td12.html一昔前風のサンプル。 td.onclick = function(){...} でイベント処理を付ける。
// 一昔前の JavaScript (IE 時代まで) for (let i=0; i<a.length; i++){ let td = a[i]; //let で宣言。var ではない点に注意。 //td に onclick の処理をつける。 td.onclick = function(){ //td が let td や const td で宣言されている場合は 1),2)どちらでも動く onclickTd(this); // 1) //onclickTd(td); // 2) }; }
参考で、let がない時代 (var を使用していた時代) の昔の JavaScript では、 2) onclickTd(td); では正常に動作しない話がありました。 this と td の違いを意識する必要があり、 混乱しやすい原因になっていました。var は現在では使用しません。
・遠い昔の JavaScript。var で変数を宣言している。 下の 1) は正常に動作する。 下の 2) の場合、どの td をクリックしても一番最後の td しか 処理されなくなる。 for (var i=0; i<a.length; i++){ var td = a[i]; //let ではなく var で宣言した場合 td.onclick = function(){ onclickTd(this); // 1)正しい。 //onclickTd(td); // 2)誤り。var td の場合は正常に動作しない。 }; }
上のサンプルは 2020年代では下のようになります。 for of と アロー関数 で記述したサンプルです。
const list = document.querySelectorAll("#TABLE1 td"); for (const td of list){ //for of で処理。td は再代入がなければ const にする。 td.onclick = event => onclickTd(td, event); // => はアロー関数 }(補足) for of とアロー関数は IE では動作しませんでした。
無名関数を使わず関数名を渡す - bind() を使用
bind() も IE 時代までの話です。
現在では アロー関数 を使った記述で間に合うので、
bind() が必要になる話はめったに出てきません。
ということですぐに眺める必要はありません。
thisの指す内容に注意、bind() のサンプル
addEventListener() でイベント処理をつける
- TestJS_event_table_td13.html
td.onclick=... の代わりに、td.addEventListener("click", ...) を使うサンプル。 初期化処理を body タグの onload="関数名()" ではなくて、 window.addEventListener("load", ...) で行います。
addEventListener() と onclick = の違い
addEventListener の方が汎用性があり、 複数のリスナーを登録することができます。
- addEventListener では同じ関数名でさまざまなイベント登録ができます。
例: element.addEventListener("click", ....); element.addEventListener("load", ....); element.addEventListener("blur", ....); window.onload = ... も window.addEventListener("load", ...); で書けます。
- addEventListener では複数のリスナーを登録することができます。
td.onclick = .... では 1つの関数しか付けられない点に注意。 関数を 2つ以上付けると、先に付けた関数が上書きされ、処理 されなくなります。 td.onclick = func1; td.onclick = func2; //func1 は無効になり処理されなくなります。
イベント処理がクラスのメソッドの場合
クラスを使った処理になると、クラスのメソッド内から 別のメソッドを呼び出すときにも this.メソッド名(); のように this を使います。 このとき this がクラスのオブジェクトとは異なる別のオブジェクトを 指しているとエラーが起こります。 JavaScript に不慣れだとよく起こるトラブルです。
例: this.メソッド名(); や this.プロパティ名 の this が window など 別のオブジェクトを指していると、not function や undefined の TypeError が出る。
こちらも IE 時代までは bind() を使っていましたが、 現在ではアロー関数の記述で間に合います。
- TestJS_event_table_td_bind03.html
イベントを付ける処理やイベント処理が クラスのメソッドの場合。
thisの指す内容に注意、bind() のサンプル