[解決済み] addEventListenerを使用したハンドラ内のthisという値について
質問
プロトタイピングでJavascriptオブジェクトを作成しました。 私は、テーブルを動的にレンダリングしようとしています。 レンダリング部分は単純でうまく動作しますが、私は動的にレンダリングされたテーブルの特定のクライアント側イベントを処理する必要があります。 これも簡単です。 問題は、イベントを処理する関数内の "this" 参照にあります。 オブジェクトを参照する代わりに、イベントを発生させた要素を参照しています。
コードを参照してください。 問題のある箇所は
ticketTable.prototype.handleCellClick = function()
:
function ticketTable(ticks)
{
// tickets is an array
this.tickets = ticks;
}
ticketTable.prototype.render = function(element)
{
var tbl = document.createElement("table");
for ( var i = 0; i < this.tickets.length; i++ )
{
// create row and cells
var row = document.createElement("tr");
var cell1 = document.createElement("td");
var cell2 = document.createElement("td");
// add text to the cells
cell1.appendChild(document.createTextNode(i));
cell2.appendChild(document.createTextNode(this.tickets[i]));
// handle clicks to the first cell.
// FYI, this only works in FF, need a little more code for IE
cell1.addEventListener("click", this.handleCellClick, false);
// add cells to row
row.appendChild(cell1);
row.appendChild(cell2);
// add row to table
tbl.appendChild(row);
}
// Add table to the page
element.appendChild(tbl);
}
ticketTable.prototype.handleCellClick = function()
{
// PROBLEM!!! in the context of this function,
// when used to handle an event,
// "this" is the element that triggered the event.
// this works fine
alert(this.innerHTML);
// this does not. I can't seem to figure out the syntax to access the array in the object.
alert(this.tickets.length);
}
どのように解決するのですか?
ハンドラをインスタンスにバインドする必要があります。
var _this = this;
function onClickBound(e) {
_this.handleCellClick.call(cell1, e || window.event);
}
if (cell1.addEventListener) {
cell1.addEventListener("click", onClickBound, false);
}
else if (cell1.attachEvent) {
cell1.attachEvent("onclick", onClickBound);
}
このイベントハンドラは
event
オブジェクト(第一引数として渡される)を正規化して
handleCellClick
を適切なコンテキストで呼び出します (つまり、イベントリスナーがアタッチされた要素を参照します)。
また、ここでのコンテキストの正規化(つまり、適切な
this
を設定すること) によって、イベントハンドラとして使われる関数 (
onClickBound
) と要素オブジェクト (
cell1
). IE のいくつかのバージョン (6 と 7) では、これはメモリリークを引き起こす可能性があり、またおそらくそうなります。このリークは、本質的には、ネイティブ オブジェクトとホスト オブジェクトの間に存在する循環参照により、ページの更新時にブラウザがメモリを解放できないことです。
これを回避するには、a) ネイティブとホスト オブジェクトの間の
this
正規化をやめる、b) 別の (より複雑な) 正規化戦略を採用する、c) ページアンロード時に既存のイベントリスナーをクリーンアップする、すなわち
removeEventListener
,
detachEvent
および要素
null
を追加しました (これは残念ながら、ブラウザの高速履歴ナビゲーションを無用の長物にしてしまいます)。
また、この処理を行う JS ライブラリを見つけることもできます。それらのほとんど (例: jQuery、Prototype.js、YUI など) は、通常 (c) で説明したようにクリーンアップを処理します。
関連
-
[解決済み] let "と "var "の使い分けは?
-
[解決済み] セレクタの子を取得する方法は?
-
[解決済み] JavaScriptでドロップダウンリストの選択値を取得する
-
[解決済み] JavaScriptでページの一番上までスクロールする?
-
[解決済み] コールバック内で正しい `this` にアクセスする方法
-
[解決済み] JavaScriptには、与えられた範囲内の範囲を生成する "range() "のようなメソッドがありますか?
-
[解決済み] JavaScriptでテキスト入力フィールドの値を取得するにはどうすればよいですか?
-
[解決済み】「GET」パラメータから値を取得する(JavaScript)【重複】。
-
[解決済み] CORS OriginヘッダーとCSRFトークンによるCSRF保護
-
[解決済み] HTML要素にスクロールバーがあるかどうかをチェックする
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] JSのDateからDay名
-
[解決済み] ExtJS 4のイベントハンドリングについて
-
[解決済み] javascriptで2つの数値を連結する方法は?
-
[解決済み] WebStormで未解決の変数が大量にある場合の警告に対処する方法は?
-
[解決済み] Javascript 空の配列の削減
-
[解決済み] AJAX Mailchimp サインアップフォームの統合
-
[解決済み] 各オブジェクトに?重複
-
[解決済み] Promise : then vs then + catch [重複].
-
[解決済み] なぜjavascriptのES6 Promisesはresolve後も実行を継続するのですか?
-
[解決済み] V8 Javascript エンジンのスタンドアロン実行