一.handleEvent とは何か
addEventListener(strEventType, func, false/true);
これが最も一般的なイベントハンドラを追加する方法でしょう。実は 2 番目のパラメータは handleEvent プロパティを持つオブジェクト也可以是です。例えば:
var obj = {
// ...
handleEvent: function() {
// ...
console.log('event fired');
}
}
document.body.addEventListener('click', obj, false);
DOM2 級イベント は add/removeEventListener, dispatchEvent, stopPropagation, preventDefault, initEvent, createEvent などのメソッドを定義しており、add/removeEventListener の 2 番目のパラメータの型は EventListener です。EventListener インターフェースの定義 では handleEvent メソッドの実装が要求されていることがわかります
言い換えれば、Eventlistener を実装する方法は 2 つあります:
-
functionオブジェクトはデフォルトでEventlistenerインターフェースを実装しています -
オブジェクトに
handleEventメソッドを実装します
詳細は DOM3 級 event listener をご覧ください
二.handleEvent を使うメリットとデメリット
1.this の向き
addEventListener('click', obj, false); 方式でイベントハンドラを追加した後、イベント処理関数 obj.handleEvent 内の this は当然 obj を指します
addEventListener(strEventType, func, false/true); 方式でイベントハンドラを追加した後、イベント処理関数 func 内の this はイベントハンドラのホスト要素を指します(簡単に言えば ele.addEventListener の ele です)。例えば:
var ele = document.getElementById('test');
function handler(e) {
console.log(this === ele); // true
}
ele.addEventListener('click', handler, false);
addEventListener('click', obj, false); を使うメリットは、obj オブジェクトのプライベートプロパティを直接使用できることです。比較してみましょう:
var obj = {
// ...
attr: 1,
handleEvent: function() {
// ...
console.log(this.attr); // undefined。イベント発火後、this はホスト要素 body を指し、body には attr 属性がないため
}
}
document.body.addEventListener('click', obj.handleEvent, false);
2.イベントハンドラの動的変更
イベントハンドラを動的に変更できます。例えば:obj.handleEvent = obj.handler2; または obj.handleEvent = fun;。非常に便利で、先に remove して add し直す必要がありません
3.デメリット
デメリットは互換性ではなく(DOM2 級イベントは IE9+ でサポートされています。つまり、addEventListener が使える場所なら obj.handleEvent も使えます)、可読性の面です。筆者は自分なりに多くの JS 関連の書籍を読んできたつもりですが、この用法を見たことがありません。そのため、書いても他人に理解してもらえるかが問題です
参考資料
- addEventListener 之 handleEvent: 原文が 404 になったため、転載版を貼ります
コメントはまだありません