【JavaScript】addEventListenerのコールバック関数に引数を渡す

JavaScript

はじめに

addEventListener() メソッド

target.addEventListener(type, listener [, options]);

target:イベントの対象となる要素

type:対象とするイベントの種類を表す文字列

listener:関数または EventListener を実装したオブジェクトを指定する

options:対象のイベントリスナーの特性を指定する

EventTarget.addEventListener() - Web API | MDN
addEventListener() は EventTarget インターフェイスのメソッドで、ターゲットに特定のイベントが配信されるたびに呼び出される関数を設定します。

よくある失敗

例としてボタンをクリックすると、引数として渡した文字列がHTMLに出力されます。

通常のやり方(引数をわたさない)

引数を渡さず、動作を確認

See the Pen コールバック関数の引数 by TKG1 (@tkg1) on CodePen.

引数を渡してみる(よくある失敗例)

コールバック関数にgetName(name)で引数を指定してみます。

See the Pen コールバック関数の引数2 by TKG1 (@tkg1) on CodePen.

ロードと共にgetName(name)関数が実行されてしまいました。また、クリックしても関数は実行されません。

理由として、関数に()または(引数)をつけると、場合によりますが、ロード共に実行され、 その返り値が第二引数に設定されるからです。
getName(name)関数は返り値が無いので、なにも設定されてないということになります。

試しにreturnnameを返してみるとエラーがおきます。

直訳:パラメータ 2 は ‘Object’ 型ではありません。

第二引数にはコールバック関数 EventListener を実装したオブジェクトを指定しなければいけません。

引数の渡し方

無名関数か、アロー関数でラップする

無名関数function() { } かアロー関数()=> { }getName(name)関数をラップします

See the Pen コールバック関数の引数3 by TKG1 (@tkg1) on CodePen.

let button = document.querySelector('button');
let nameList = document.querySelector('#name');

button.addEventListener('click', ()=> {
  getName('タゴサク')
});

function getName(name) {
  let li = document.createElement("li");
  li.textContent = name;
  nameList.appendChild(li);
}

bind()メソッドを使用する

bind()メソッドはthis の値と初期の引数を指定された関数のをコピーします。

See the Pen コールバック関数の引数4 by TKG1 (@tkg1) on CodePen.

let button = document.querySelector('button');
let nameList = document.querySelector('#name');

let getName = function() {
  let li = document.createElement("li");
  li.textContent = this;
  nameList.appendChild(li);
}

button.addEventListener('click', getName.bind('タゴサク'));

getName.bind()getNameの中の関数をバインド(コピー)します。

bind()の第一引数にはthisの値を設定できます。(第二引数以降は特定の引数)

後はthisを関数内で受け取ればOK。

thisを利用しないやり方

let button = document.querySelector('button');
let nameList = document.querySelector('#name');


let getName = function(name) {
  let li = document.createElement("li");
  li.textContent = name;
  nameList.appendChild(li);
}

button.addEventListener('click', getName.bind(null, 'タゴサク'));

bind()の第一引数をnull、第二引数はfunction(name)nameに渡される。

Function.prototype.bind() - JavaScript | MDN
bind() メソッドは新しい関数を生成し、これは呼び出された際に this キーワードに指定された値が設定されます。この値は新しい関数が呼び出されたとき、一連の引数の前に置かれます。

JavaScriptのthisは他の言語より自由なので、その違いを理解する必要があります。

オブジェクトメソッド, "this"

第二引数にオブジェクトを渡してやる(ただし、handleEventメソッドが必要)

See the Pen コールバック関数の引数 by TKG1 (@tkg1) on CodePen.

let button = document.querySelector('button');
let nameList = document.querySelector('#name');

function getName(e) {
  let li = document.createElement("li");
  li.textContent = this.name;
  nameList.appendChild(li);
}

button.addEventListener('click', { name: 'タゴサク', handleEvent: getName});

実行したいメソッドをhandleEvent: getName、渡したい引数をname: 'タゴサク'とする。

渡された引数がオブジェクトなので、関数内でthis.nameで参照できます。

getName(e)eにはイベントの情報が渡されます。

コールバック関数の返り値を関数にする

こんな書き方もありました

See the Pen コールバック関数の引数6 by TKG1 (@tkg1) on CodePen.

let button = document.querySelector('button');
let nameList = document.querySelector('#name');

button.addEventListener('click', getName('タゴサク'));

function getName(name){
  return function(){
    let li = document.createElement("li");
    li.textContent = name;
    nameList.appendChild(li);
  }
}

返り値が関数なので、問題なく動作します。

まとめ

やり方は色々ありますが、一手間加えないとremoveEventListenerが使用できないものもありますので、注意が必要です。

これらのやり方は、setTimeoutなどコールバック関数を指定するメソッドでも一部使用できます。

コメント

タイトルとURLをコピーしました