web-dev-qa-db-ja.com

Uncaught TypeError:addEventListenerでの不正な呼び出し

EventListenerを置くこの試みの両方のバージョンで_Uncaught TypeError: Illegal invocation_を取得します:(ターゲットをクリックしたときではなく、リスナーを追加する必要があるときにエラーが発生します)

ronan.addEventListener("click", alert, false);

addEventListener.apply(ronan, ["click", alert, false]);

ronanはコンソールから正常に返されるdiv要素なので、それが問題だとは思いません。このエラーが発生する理由はありますか? this スレッドを読みましたが、それからは理解できませんでした。

15
Artur Sapek

alertを関数でラップする必要があります。これは機能します:

ronan.addEventListener("click", function() { alert('Hi'); }, false);

これが証明のための フィドル です。リスナーが実行されると、その関数内のalertの値が、それがリッスンしているオブジェクトに設定されるため、thisを単独で使用することは機能しません。たとえば、リスナーをronanに設定すると、そのリスナー内でthis === ronanになります。この関数はalertthisと等しいことを期待しているため、これはwindowに問題をもたらします。関数を別の関数でラップするか、thisが期待するものにバインドすることで、これを回避できます(しゃれは意図されていません)。

document.body.addEventListener('click', alert.bind(window), false);

IE <9では、attachEventではなくaddEventListenerを使用する必要があることを忘れないでください。


apply/calladdEventListener

まったく別の関数であるwindow.addEventListenerとは対照的に、引数をHTMLElement.prototype.addEventListenerに適用しようとしているため、2回目の試行は機能しません。

// This won't work
addEventListener.apply(ronan, ["click", alert.bind(window), false]);

// This will work
HTMLElement.prototype.addEventListener.apply(ronan, ['click', alert.bind(window), false]);