Der Wert von "this" innerhalb des Handlers mit addEventListener
Habe ich erstellt ein javascript-Objekt per prototyping. Ich bin versucht zu Rendern einer Tabelle dynamisch. Während der rendering-Teil ist einfach und funktioniert gut, ich muss auch mit bestimmten client-Seite Ereignisse für die dynamisch dargestellten Tabelle. Auch das ist einfach. Wo habe ich Probleme mit dem "this" - Referenz innerhalb der Funktion, die das Ereignis behandelt. Anstelle von "this" referenziert das Objekt, ist es, die Verweise auf das element, das das Ereignis ausgelöst hat.
Siehe code. Der problematische Bereich ist in "ticketTable.der Prototyp.handleCellClick = Funktion()"
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);
}
InformationsquelleAutor der Frage Darthg8r | 2009-08-27
Du musst angemeldet sein, um einen Kommentar abzugeben.
Müssen Sie die "bind" - handler zu Ihrer Instanz.
Beachten Sie, dass die event-handler hier normalisiert
event
Objekts (übergeben als ersten argument) und rufthandleCellClick
im richtigen Kontext (d.h. bezogen auf ein element, das befestigt war Ereignis-listener).Beachten Sie auch, dass Kontext Normalisierung hier (also das setzen der richtigen
this
im event-handler) entsteht ein Zirkelbezug zwischen der Funktion als event-handler (onClickBound
) und ein element Objekt (cell1
). In einigen Versionen des IE (6 und 7) dies kann, und wird wahrscheinlich, führen zu einem Speicherverlust. Dieses Loch im wesentlichen ist die browser Versagen, um Speicher freizugeben, auf Seite aktualisieren wegen Zirkelbezug zwischen einheimischen und host-Objekt.Um es zu umgehen, müssen Sie entweder a) die drop -
this
Normalisierung; b) Verwendung von alternativen (und komplexer) Normalisierung Strategie; c) die "clean-up" vorhandenen Ereignis-Listener auf Seite entladen, d.h. durch die Verwendung vonremoveEventListener
detachEvent
und Elementenull
ing (leider machen würde-Browser " schnelle Geschichte navigation nutzlos).Können Sie auch eine JS-Bibliothek kümmert sich um diese. Die meisten von Ihnen (z.B.: jQuery, Prototype.js YUI, etc.) in der Regel handle Bereinigungen, wie beschrieben in (c).
InformationsquelleAutor der Antwort kangax
Können Sie binden können Sie den Wert angeben, der verwendet werden sollte, da diese für alle Anrufe zu einer bestimmten Funktion.
Ein problem in dem Beispiel oben ist, dass man nicht entfernen Sie die Hörer-Bindung. Eine andere Lösung ist mit einer speziellen Funktion namens handleEvent zu fangen alle events:
Wie immer mdn ist die beste :). Ich kopiere einfach nur geklebt das Teil als Antwort auf diese Frage.
InformationsquelleAutor der Antwort gagarine
Auch, eine weitere Möglichkeit ist die Verwendung der EventListener-Schnittstelle (ab DOM2 !! Sich Fragen, warum niemand erwähnt es, wenn man bedenkt es ist der sauberste Weg und bedeutete für genau so eine situation.)
I. e, statt einer übergabe einer callback-Funktion übergeben Sie ein Objekt implementiert EventListener-Interface. Einfach ausgedrückt, es bedeutet nur, Sie sollten haben eine Eigenschaft, die in dem Objekt namens "handleEvent" , die Punkte, um die event-handler-Funktion. Der wesentliche Unterschied hier ist, innerhalb der Funktion
this
beziehen sich auf das übergebene Objekt dieaddEventListener
. Das istthis.theTicketTable
wird die Objekt-Instanz im belowCode. Um zu verstehen, was ich meine, schauen Sie sich den geänderten code gezielt:InformationsquelleAutor der Antwort
Ich weiß, das ist ein älterer Beitrag, aber Sie können auch weisen Sie einfach der Zusammenhang einer Variablen
self
werfen Sie Ihre Funktion in eine anonyme Funktion aufruft, die Ihre Funktion mit.call(self)
und vergeht im Rahmen.Funktioniert dies besser als "akzeptierte Antwort" weil der Zusammenhang nicht zugewiesen werden müssen eine variable für die ganze Klasse oder global, es ist eher ordentlich verstaut innerhalb der gleichen Methode, die Listener für das event.
InformationsquelleAutor der Antwort Tom Doe
Stark beeinflusst von kamathln und gagarine die Antwort, die ich dachte, ich könnte bewältigen.
Dachte ich könnte Sie wahrscheinlich gewinnen ein bisschen mehr Freiheit, wenn Sie handeCellClick in einer callback-Liste und verwenden Sie ein Objekt mit Hilfe der EventListener-Schnittstelle auf das Ereignis zum auslösen des callback-Liste-Methoden mit der richtigen diese.
InformationsquelleAutor der Antwort niall.campbell
Was
e.currentTarget Punkte, um das Ziel die gebunden ist an das "click-Ereignis" (das element, das das Ereignis ausgelöst hat), während
bind(this) bewahrt die outerscope Wert von
this
im inneren der click-Ereignis-Funktion.Wenn Sie möchten, um eine genaue Ziel geklickt haben, verwenden e.Ziel statt.
InformationsquelleAutor der Antwort DevWL