JavaScript Event Proxy
Event-Proxys sind eine sehr nützliche und interessante Funktion in der JS-Welt. Wenn wir vielen Elementen Ereignisse hinzufügen müssen, können wir die Handler-Funktion auslösen, indem wir das Ereignis zu ihrem übergeordneten Knoten hinzufügen und das Ereignis an den übergeordneten Knoten delegieren.
Dies ist hauptsächlich auf den Event-Bubbling-Mechanismus des Browsers zurückzuführen. Lassen Sie uns ein konkretes Beispiel geben, um die Verwendung dieser Funktion zu erläutern.
Dieses Beispiel stammt hauptsächlich aus David Walshs verwandtem Artikel (How JavaScript Event Delegation Works).
Angenommen, es gibt einen übergeordneten Knoten von UL, der viele untergeordnete Knoten von Li enthält:
<ul id="list"> <li id="li-1">Li 1</li> <li id="li-2">Li 2</li> <li id="li-3">Li 3</li> <li id="li-4">Li 4</li> <li id="li-5">Li 5</li> </ul>
Wenn sich unsere Maus manchmal über Li bewegt, passiert es Es ist erforderlich, die relevanten Informationen dieses Li abzurufen und das schwebende Fenster zur Anzeige detaillierter Informationen aufzurufen. Wenn ein Li angeklickt wird, muss das entsprechende Verarbeitungsereignis ausgelöst werden.
Unsere übliche Schreibweise besteht darin, jedem Li einige Ereignis-Listener wie onMouseOver oder onClick hinzuzufügen.
function addListenersLi(liElement) { liElement.onclick = function clickHandler() { //TODO }; liElement.onmouseover = function mouseOverHandler() { //TODO } } window.onload = function() { var ulElement = document.getElementById("list"); var liElements = ulElement.getElementByTagName("Li"); for (var i = liElements.length - 1; i >= 0; i--) { addListenersLi(liElements[i]); } }
Wenn die Li-Unterelemente in diesem UL häufig hinzugefügt oder gelöscht werden, müssen wir jedes Mal, wenn Li hinzugefügt wird, die Methode addListenersLi aufrufen Handler-Funktion für jeden Li-Knoten.
Dadurch wird der Vorgang zum Hinzufügen oder Löschen komplex und es besteht die Möglichkeit von Fehlern.
Die Lösung des Problems besteht darin, den Ereignis-Proxy-Mechanismus zu verwenden. Wenn das Ereignis an den oberen übergeordneten Knoten geworfen wird, ermitteln und erhalten wir die Ereignisquelle Li, indem wir das Zielobjekt (Ziel) des Ereignisses überprüfen.
Der folgende Code kann den gewünschten Effekt erzielen:
/ 获取父节点,并为它添加一个click事件 document.getElementById("list").addEventListener("click",function(e) { // 检查事件源e.targe是否为Li if(e.target && e.target.nodeName.toUpperCase == "LI") { // //TODO console.log("List item ",e.target.id," was clicked!"); } });
Wenn auf den untergeordneten Knoten geklickt wird, wird der Das Click-Ereignis wird ausgehend von den untergeordneten Knoten nach oben sprudeln. Nachdem der übergeordnete Knoten das Ereignis erfasst hat, bestimmt er anhand von e.target.nodeName, ob es sich um den Knoten handelt, den wir verarbeiten müssen. Und erhalten Sie den angeklickten Li-Knoten über e.target. Auf diese Weise können die entsprechenden Informationen gewonnen und verarbeitet werden.
Die Delegatfunktion in jQuery und Dojo
Sehen wir uns an, wie die in Dojo und jQuery bereitgestellte Ereignis-Proxy-Schnittstelle verwendet wird.
jQuery:
$("#list").delegate("li", "click", function(){ // "$(this)" is the node that was clicked console.log("you clicked a link!",$(this)); });
Die Delegate-Methode von jQuery erfordert drei Parameter, einen Selektor, einen Zeitnamen und einen Ereignishandler.
Dojo ähnelt jQuery, der einzige Unterschied besteht im Programmierstil der beiden:
require(["dojo/query","dojox/NodeList/delegate"], function(query,delegate){ query("#list").delegate("li","onclick",function(event) { // "this.node" is the node that was clicked console.log("you clicked a link!",this); }); })
Dojos Delegate-Modul befindet sich in dojox.NodeList Die bereitgestellte Schnittstelle ist dieselbe wie bei jQuery und die Parameter sind ebenfalls dieselben.
Durch die Delegation können Sie mehrere Vorteile der Verwendung der Ereignisdelegation für die Entwicklung nutzen:
1. Es müssen weniger Funktionen verwaltet werden. Es ist nicht erforderlich, für jedes Element eine Listener-Funktion hinzuzufügen. Für ähnliche untergeordnete Elemente unter demselben übergeordneten Knoten können Ereignisse behandelt werden, indem sie an die Überwachungsfunktion des übergeordneten Elements delegiert werden.
2. Sie können Elemente problemlos dynamisch hinzufügen und ändern, und es ist nicht erforderlich, Ereignisbindungen aufgrund von Änderungen an Elementen zu ändern.
3. Es gibt weniger Verbindungen zwischen JavaScript- und DOM-Knoten, was die Wahrscheinlichkeit von Speicherlecks durch Zirkelverweise verringert.
Verwendung von Proxys in der JavaScript-Programmierung
Oben wird beschrieben, wie Sie den Browser-Bubbling-Mechanismus verwenden, um bei der Verarbeitung von DOM-Ereignissen Ereignis-Proxys zu DOM-Elementen hinzuzufügen. Tatsächlich können wir in der reinen JS-Programmierung dieses Programmiermodell auch verwenden, um Proxy-Objekte zum Betreiben von Zielobjekten zu erstellen
var delegate = function(client, clientMethod) { return function() { return clientMethod.apply(client, arguments); } } var Apple= function() { var _color = "red"; return { getColor: function() { console.log("Color: " + _color); }, setColor: function(color) { _color = color; } }; }; var a = new Apple(); var b = new Apple(); a.getColor(); a.setColor("green"); a.getColor(); //调用代理 var d = delegate(a, a.setColor); d("blue"); //执行代理 a.getColor(); //b.getColor();
Im obigen Beispiel durch Aufrufen von The Die Funktion „delegate()“ erstellt eine Proxy-Funktion d, um die Änderung von a durchzuführen.
Obwohl diese Methode die Übertragung des aufrufenden Objekts mithilfe von „Anwenden“ realisiert, verbirgt sie bestimmte Objekte vor dem Programmiermodus und kann den zufälligen Zugriff auf diese Objekte verhindern.
Das Konzept der Delegation wird in vielen Frameworks verwendet, um den laufenden Umfang von Methoden festzulegen.
Typische sind dojo.hitch(scope, method) und createDelegate(obj, args) von ExtJS.
Das obige ist der detaillierte Inhalt vonAusführliche Erläuterung des JavaScript-Ereignis-Proxys und der Verwendung der Proxy-Instanz. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!