gorogoronyan FC2

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 タグでは

  1. 多くの td がある table で個別に onlick=... を書くのは面倒です。
    繰り返し同じ記述が出てきます。 JavaScript で一括登録の処理にしたい場合もあります。
  2. table 自体を JavaScript で作成する場合は上の方法が使えません。
    HTML にはじめから table タグや td タグが存在していない場合は 上のような記述ができません。

ということで、td に onclick= をつける処理も JavaScript 化します。下に続く。

JavaScript で td にイベント処理をつける

1) 元のサンプル

最初に元のサンプルです。

TestJS_event_table_td11.html
table の セル(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 でまとめる

function initTable(){
    //table 内の td 要素をすべて取り出す。
    const list = document.querySelectorAll("#TABLE1 td");
    //td にクリックイベントを付ける。
    for (const td of list){
        td.onclick = event => onclickTd(td, event);  // => はアロー関数です。
    }
}

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() でイベント処理をつける

addEventListener() と onclick = の違い

addEventListener の方が汎用性があり、 複数のリスナーを登録することができます。

  1. addEventListener では同じ関数名でさまざまなイベント登録ができます。
    例:
    element.addEventListener("click", ....);
    element.addEventListener("load", ....);
    element.addEventListener("blur", ....);
    
    window.onload = ... も window.addEventListener("load", ...); 
    で書けます。
    
  2. 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() を使っていましたが、 現在ではアロー関数の記述で間に合います。

関連

inserted by FC2 system