イベントハンドラ中のthisの取り扱いに関するメモ
イベントハンドラ中のthisは混乱のもと
(略)
"this"はshiraishiオブジェクトではなく、ボタンのDOMオブジェクトになってしまいます。
混乱のもとなのは分かるけど、それをどう解決すればいいのかについて上記記事はふれていない。
おかげで、はまった。
つまりどんな状況かというと
まちがいのコード
var Monster = function() {}; Monster.prototype = { name: null, func: function() { alert(this.name + " has shown up."); }, init: function(id) { // まちがい document.getElementById(id).addEventListener("click", this.func, false); } }; window.onload = function() { monsterA = new Monster(); monsterA.name = "Slime"; monsterA.init("target"); };
Monster.prototype.initで、引数で渡された要素にonClickイベントを定義したいんだけど、上のような書き方ではダメ。このthisはMonsterオブジェクトではなく、要素のDOMオブジェクトを指すからだ。
結局どうすれば良いかというと———
修正後のコード
var Monster = function() {}; Monster.prototype = { name: null, func: function() { alert(this.name + " has shown up."); }, init2: function(id) { document.getElementById(id).addEventListener("click", (function(obj){return function(){obj.func();};})(this), false); } }; window.onload = function() { monsterA = new Monster(); monsterA.name = "Slime"; monsterA.init("target"); };
何か複雑だが、こんなクロージャを書くと動いた。
もっと良い方法は
prototype.jsを使うべき。