Was ist eine DOM-Ereignisdelegation?


201

Kann jemand bitte die Ereignisdelegierung in JavaScript erklären und wie ist es nützlich?


2
Es ist schön, wenn es einen Link zu einer nützlichen Informationsquelle gibt. 6 Stunden später ist dies der Google-Top-Hit für "Dom Event Delegation". Vielleicht ist dies ein nützlicher Link? Ich bin nicht ganz sicher: w3.org/TR/DOM-Level-2-Events/events.html
Sean McMillan


7
Dies ist eine beliebte. Sogar fb Jungs verlinken darauf für ihre Reaktionsseite davidwalsh.name/event-delegate
Sorter

Sehen Sie diese javascript.info/event-delegation, es wird Ihnen sehr helfen
Suraj Jain

Antworten:


329

Die DOM-Ereignisdelegation ist ein Mechanismus zum Reagieren auf UI-Ereignisse über einen einzigen gemeinsamen Elternteil und nicht über jedes Kind, durch die Magie des "Sprudelns" des Ereignisses (auch bekannt als Ereignisausbreitung).

Wenn ein Ereignis für ein Element ausgelöst wird, tritt Folgendes auf :

Das Ereignis wird an sein Ziel gesendet EventTargetund alle dort gefundenen Ereignis-Listener werden ausgelöst. Bubbling- Ereignisse lösen dann alle zusätzlichen Ereignis-Listener aus, die gefunden werden, indem Sie der EventTargetübergeordneten Kette des Ereignisses nach oben folgen und nach Ereignis-Listenern suchen, die in jedem aufeinanderfolgenden EventTarget registriert sind. Diese Ausbreitung nach oben wird bis einschließlich der Document.

Das Bubbling von Ereignissen bildet die Grundlage für die Ereignisdelegierung in Browsern. Jetzt können Sie einen Ereignishandler an ein einzelnes übergeordnetes Element binden. Dieser Handler wird ausgeführt, wenn das Ereignis auf einem seiner untergeordneten Knoten (und einem seiner untergeordneten Knoten) auftritt . Dies ist eine Ereignisdelegation. Hier ist ein Beispiel dafür in der Praxis:

<ul onclick="alert(event.type + '!')">
    <li>One</li>
    <li>Two</li>
    <li>Three</li>
</ul>

Wenn Sie in diesem Beispiel auf einen der untergeordneten <li>Knoten klicken , wird eine Warnung angezeigt "click!", obwohl kein Klick-Handler an den <li>angeklickten Knoten gebunden ist . Wenn wir an onclick="..."jeden gebunden <li>wären, würden Sie den gleichen Effekt erzielen.

Was ist der Vorteil?

Stellen Sie sich vor, Sie müssen jetzt <li>über die DOM-Manipulation dynamisch neue Elemente zur obigen Liste hinzufügen :

var newLi = document.createElement('li');
newLi.innerHTML = 'Four';
myUL.appendChild(newLi);

Ohne Ereignisdelegierung müssten Sie den "onclick"Ereignishandler erneut an das neue <li>Element binden , damit er sich wie seine Geschwister verhält . Mit der Ereignisdelegierung müssen Sie nichts tun. Fügen Sie einfach das Neue <li>zur Liste hinzu und Sie sind fertig.

Dies ist absolut fantastisch für Web-Apps mit Event-Handlern, die an viele Elemente gebunden sind und in denen neue Elemente dynamisch im DOM erstellt und / oder entfernt werden. Mit der Ereignisdelegierung kann die Anzahl der Ereignisbindungen drastisch verringert werden, indem sie in ein gemeinsames übergeordnetes Element verschoben werden, und Code, der im laufenden Betrieb dynamisch neue Elemente erstellt, kann von der Logik der Bindung ihrer Ereignishandler entkoppelt werden.

Ein weiterer Vorteil der Ereignisdelegierung besteht darin, dass der gesamte Speicherbedarf, der von Ereignis-Listenern verwendet wird, abnimmt (da die Anzahl der Ereignisbindungen abnimmt). Bei kleinen Seiten, die häufig entladen werden (dh, der Benutzer navigiert häufig zu verschiedenen Seiten), macht dies möglicherweise keinen großen Unterschied. Für langlebige Anwendungen kann dies jedoch von Bedeutung sein. Es gibt einige wirklich schwer auffindbare Situationen, in denen Elemente, die aus dem DOM entfernt wurden, immer noch Speicher beanspruchen (dh sie lecken), und häufig ist dieser durchgesickerte Speicher an eine Ereignisbindung gebunden. Mit der Ereignisdelegierung können Sie untergeordnete Elemente zerstören, ohne das Risiko zu vergessen, die Ereignis-Listener zu "entbinden" (da sich der Listener auf dem Vorfahren befindet). Diese Arten von Speicherlecks können dann eingedämmt werden (wenn sie nicht beseitigt werden, was manchmal verdammt schwer zu tun ist. IE, ich sehe dich an).

Hier sind einige bessere konkrete Codebeispiele für die Ereignisdelegierung:


4
Gute Antwort! Ich war lange Zeit verwirrt darüber, aber dieses Beispiel machte es mir kristallklar.
Cofey

Ich habe keinen Zugriff beim Öffnen Ihres dritten Links. Ereignisdelegation ohne Javascript-Bibliothek und +1 für Ihren letzten Link
bugwheels94

Hallo, danke für eine tolle Erklärung. Ich bin jedoch immer noch verwirrt über ein bestimmtes Detail: Wie ich den Ereignisfluss im DOM-Baum verstehe (wie in 3.1 zu sehen ist . Ereignisversand und DOM-Ereignisfluss ), breitet sich das Ereignisobjekt aus, bis es das Zielelement erreicht, und sprudelt dann hoch. Wie kommt es, dass untergeordnete Elemente eines Knotens erreicht werden können, wenn das übergeordnete Element dieses Knotens das betreffende Ereignisziel ist? zB wie kann sich das Ereignis zu einem <li>Zeitpunkt ausbreiten, an dem es anhalten soll <ul>? Wenn meine Frage noch unklar ist oder einen separaten Thread benötigt, würde ich mich freuen, sie zu verpflichten.
Aetos

@Aetos: > Wie kommt es, dass untergeordnete Elemente eines Knotens erreicht werden können, wenn das übergeordnete Element dieses Knotens das betreffende Ereignisziel ist? Es kann nicht, wie ich es verstehe. Das Ereignis beendet Phase 1 (Erfassung) am übergeordneten Ziel, tritt in Phase 2 (Ziel) am Ziel selbst ein und tritt dann in Phase 3 (Sprudeln) ein, beginnend am übergeordneten Ziel. Nirgendwo erreicht es ein Kind des Ziels.
Crescent Fresh

1
Wirklich tolle Antwort. Vielen Dank, dass Sie die Delegation von Veranstaltungen mit relevanten Fakten erklärt haben. Vielen Dank!
Kshitij Tiwari

30

Mit der Ereignisdelegierung können Sie vermeiden, bestimmten Knoten Ereignis-Listener hinzuzufügen. Stattdessen wird der Ereignis-Listener einem übergeordneten Element hinzugefügt. Dieser Ereignis-Listener analysiert sprudelnde Ereignisse, um eine Übereinstimmung mit untergeordneten Elementen zu finden.

JavaScript Beispiel:

Angenommen, wir haben ein übergeordnetes UL-Element mit mehreren untergeordneten Elementen:

<ul id="parent-list">
<li id="post-1">Item 1</li>
<li id="post-2">Item 2</li>
<li id="post-3">Item 3</li>
<li id="post-4">Item 4</li>
<li id="post-5">Item 5</li>
<li id="post-6">Item 6</li>

Nehmen wir auch an, dass etwas passieren muss, wenn auf jedes untergeordnete Element geklickt wird. Sie können jedem einzelnen LI-Element einen separaten Ereignis-Listener hinzufügen. Was ist jedoch, wenn LI-Elemente häufig hinzugefügt und aus der Liste entfernt werden? Das Hinzufügen und Entfernen von Ereignis-Listenern wäre ein Albtraum, insbesondere wenn sich der Code zum Hinzufügen und Entfernen an verschiedenen Stellen in Ihrer App befindet. Die bessere Lösung besteht darin, dem übergeordneten UL-Element einen Ereignis-Listener hinzuzufügen. Wenn Sie jedoch den Ereignis-Listener zum übergeordneten Element hinzufügen, woher wissen Sie dann, auf welches Element geklickt wurde?

Einfach: Wenn das Ereignis zum UL-Element sprudelt, überprüfen Sie die Zieleigenschaft des Ereignisobjekts, um einen Verweis auf den tatsächlich angeklickten Knoten zu erhalten. Hier ist ein sehr einfaches JavaScript-Snippet, das die Ereignisdelegierung veranschaulicht:

// Get the element, add a click listener...
document.getElementById("parent-list").addEventListener("click", function(e) {
// e.target is the clicked element!
// If it was a list item
if(e.target && e.target.nodeName == "LI") {
    // List item found!  Output the ID!
    console.log("List item ", e.target.id.replace("post-"), " was clicked!");
       }
 });

Fügen Sie dem übergeordneten Element zunächst einen Listener für Klickereignisse hinzu. Wenn der Ereignis-Listener ausgelöst wird, überprüfen Sie das Ereigniselement, um sicherzustellen, dass es der Elementtyp ist, auf den reagiert werden soll. Wenn es ein LI-Element ist, boom: Wir haben, was wir brauchen! Wenn es sich nicht um ein Element handelt, das wir möchten, kann das Ereignis ignoriert werden. Dieses Beispiel ist ziemlich einfach - UL und LI sind ein direkter Vergleich. Versuchen wir etwas Schwierigeres. Lassen Sie uns einen Eltern-DIV mit vielen Kindern haben, aber alles, was uns wichtig ist, ist ein A-Tag mit der Klasse-CSS-Klasse:

  // Get the parent DIV, add click listener...
  document.getElementById("myDiv").addEventListener("click",function(e) {
// e.target was the clicked element
if(e.target && e.target.nodeName == "A") {
    // Get the CSS classes
    var classes = e.target.className.split(" ");
    // Search for the CSS class!
    if(classes) {
        // For every CSS class the element has...
        for(var x = 0; x < classes.length; x++) {
            // If it has the CSS class we want...
            if(classes[x] == "classA") {
                // Bingo!
                console.log("Anchor element clicked!");
                // Now do something here....
            }
        }
    }

  }
});

http://davidwalsh.name/event-delegate


1
Vorgeschlagene Optimierung: Verwenden Sie stattdessen e.classList.contains () im letzten Beispiel: developer.mozilla.org/en-US/docs/Web/API/Element/classList
nc.

7

Die Delegation von Dom-Events unterscheidet sich von der Definition der Informatik.

Es bezieht sich auf die Behandlung von sprudelnden Ereignissen aus vielen Elementen, wie z. B. Tabellenzellen, aus einem übergeordneten Objekt wie der Tabelle. Dies kann den Code einfacher halten, insbesondere beim Hinzufügen oder Entfernen von Elementen, und spart Speicherplatz.


6

Die Delegierung ist eine Technik, bei der ein Objekt ein bestimmtes Verhalten nach außen ausdrückt, in Wirklichkeit jedoch die Verantwortung für die Implementierung dieses Verhaltens an ein zugeordnetes Objekt delegiert. Dies klingt zunächst sehr ähnlich wie das Proxy-Muster, dient jedoch einem ganz anderen Zweck. Die Delegierung ist ein Abstraktionsmechanismus, der das Verhalten von Objekten (Methoden) zentralisiert.

Allgemein gesprochen: Verwenden Sie die Delegierung als Alternative zur Vererbung. Vererbung ist eine gute Strategie, wenn eine enge Beziehung zwischen übergeordnetem und untergeordnetem Objekt besteht, Vererbung jedoch Objekte sehr eng koppelt. Delegation ist häufig die flexiblere Möglichkeit, eine Beziehung zwischen Klassen auszudrücken.

Dieses Muster wird auch als "Proxy-Ketten" bezeichnet. Einige andere Entwurfsmuster verwenden die Delegierung - die Status-, Strategie- und Besuchermuster hängen davon ab.


Gute Erklärung. Im Beispiel des <ul> mit mehreren <li> Kindern sind es anscheinend diejenigen, die mit der Klicklogik umgehen, aber das ist nicht so, weil sie diese Logik im Vater <ul>
Juanma Menendez

6

Das Delegationskonzept

Wenn sich in einem übergeordneten Element viele Elemente befinden und Sie Ereignisse für diese Elemente verarbeiten möchten, binden Sie keine Handler an jedes Element. Binden Sie stattdessen den einzelnen Handler an das übergeordnete Element und rufen Sie das untergeordnete Element aus event.target ab. Diese Site bietet nützliche Informationen zum Implementieren der Ereignisdelegierung. http://javascript.info/tutorial/event-delegation


6

Bei der Ereignisdelegierung wird ein Ereignis behandelt, das mithilfe eines Ereignishandlers für ein Containerelement sprudelt , das Verhalten des Ereignishandlers jedoch nur aktiviert, wenn das Ereignis für ein Element im Container aufgetreten ist, das einer bestimmten Bedingung entspricht. Dies kann die Behandlung von Ereignissen für Elemente im Container vereinfachen.

Angenommen, Sie möchten einen Klick auf eine Tabellenzelle in einer großen Tabelle ausführen. Sie können eine Schleife schreiben, um einen Klick-Handler an jede Zelle anzuschließen ... oder Sie können einen Klick-Handler an die Tabelle anschließen und die Ereignisdelegierung verwenden, um sie nur für Tabellenzellen (und nicht für Tabellenüberschriften oder das Leerzeichen in a) auszulösen Reihe um Zellen usw.).

Dies ist auch nützlich, wenn Sie Elemente zum Container hinzufügen und daraus entfernen möchten, da Sie sich nicht um das Hinzufügen und Entfernen von Ereignishandlern für diese Elemente kümmern müssen. Haken Sie das Ereignis einfach in den Container ein und behandeln Sie das Ereignis, wenn es sprudelt.

Hier ist ein einfaches Beispiel (es ist absichtlich ausführlich, um eine Inline-Erklärung zu ermöglichen): Behandeln eines Klicks auf ein tdElement in einer Containertabelle:

// Handle the event on the container
document.getElementById("container").addEventListener("click", function(event) {
    // Find out if the event targeted or bubbled through a `td` en route to this container element
    var element = event.target;
    var target;
    while (element && !target) {
        if (element.matches("td")) {
            // Found a `td` within the container!
            target = element;
        } else {
            // Not found
            if (element === this) {
                // We've reached the container, stop
                element = null;
            } else {
                // Go to the next parent in the ancestry
                element = element.parentNode;
            }
        }
    }
    if (target) {
        console.log("You clicked a td: " + target.textContent);
    } else {
        console.log("That wasn't a td in the container table");
    }
});
table {
    border-collapse: collapse;
    border: 1px solid #ddd;
}
th, td {
    padding: 4px;
    border: 1px solid #ddd;
    font-weight: normal;
}
th.rowheader {
    text-align: left;
}
td {
    cursor: pointer;
}
<table id="container">
    <thead>
        <tr>
            <th>Language</th>
            <th>1</th>
            <th>2</th>
            <th>3</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <th class="rowheader">English</th>
            <td>one</td>
            <td>two</td>
            <td>three</td>
        </tr>
        <tr>
            <th class="rowheader">Español</th>
            <td>uno</td>
            <td>dos</td>
            <td>tres</td>
        </tr>
        <tr>
            <th class="rowheader">Italiano</th>
            <td>uno</td>
            <td>due</td>
            <td>tre</td>
        </tr>
    </tbody>
</table>

Bevor wir auf die Details eingehen, möchten wir uns daran erinnern, wie DOM-Ereignisse funktionieren.

DOM-Ereignisse werden vom Dokument an das Zielelement (die Erfassungsphase ) gesendet und dann vom Zielelement zurück zum Dokument (die Blasenphase ) geleitet. Diese Grafik in der alten DOM3-Ereignisspezifikation (jetzt ersetzt, aber die Grafik ist noch gültig) zeigt es wirklich gut:

Geben Sie hier die Bildbeschreibung ein

Nicht alle Ereignisse sprudeln, aber die meisten, einschließlich click.

Die Kommentare im obigen Codebeispiel beschreiben, wie es funktioniert. matchesprüft, ob ein Element mit einem CSS-Selektor übereinstimmt, aber Sie können natürlich auch prüfen, ob etwas Ihren Kriterien auf andere Weise entspricht, wenn Sie keinen CSS-Selektor verwenden möchten.

Dieser Code wird geschrieben verbosely die einzelnen Schritte zu rufen, sondern auf vage modernen Browsern (und auf IE auch wenn Sie eine polyfill verwenden), können Sie verwenden , closestund containsstatt der Schleife:

var target = event.target.closest("td");
    console.log("You clicked a td: " + target.textContent);
} else {
    console.log("That wasn't a td in the container table");
}

Live-Beispiel:

closestÜberprüft das Element, auf das Sie es aufrufen, um festzustellen, ob es mit dem angegebenen CSS-Selektor übereinstimmt, und gibt in diesem Fall dasselbe Element zurück. Wenn nicht, überprüft es das übergeordnete Element, um festzustellen, ob es übereinstimmt, und gibt das übergeordnete Element zurück, wenn dies der Fall ist. Wenn nicht, überprüft es das übergeordnete Element des Elternteils usw. Es findet also das "nächstgelegene" Element in der Ahnenliste, das dem Selektor entspricht. Da dies möglicherweise über das Containerelement hinausgeht, containsüberprüft der obige Code , ob sich ein passendes Element im Container befindet. Wenn Sie das Ereignis in den Container einbinden, haben Sie angegeben, dass Sie nur Elemente in diesem Container behandeln möchten .

Zurück zu unserem Tabellenbeispiel: Wenn Sie eine Tabelle in einer Tabellenzelle haben, stimmt diese nicht mit der Tabellenzelle überein, die die Tabelle enthält:


3

Es ist im Grunde, wie die Assoziation mit dem Element hergestellt wird. .clickgilt für das aktuelle DOM, während .on(unter Verwendung der Delegierung) weiterhin für neue Elemente gültig ist, die dem DOM nach der Ereigniszuordnung hinzugefügt wurden.

Was besser zu benutzen ist, würde ich sagen, es hängt vom Fall ab.

Beispiel:

<ul id="todo">
   <li>Do 1</li>
   <li>Do 2</li>
   <li>Do 3</li>
   <li>Do 4</li>
</ul>

.Klickereignis:

$("li").click(function () {
   $(this).remove ();
});

Ereignis .on:

$("#todo").on("click", "li", function () {
   $(this).remove();
});

Beachten Sie, dass ich den Selektor in der .on getrennt habe. Ich werde erklären warum.

Nehmen wir an, dass wir nach dieser Assoziation Folgendes tun:

$("#todo").append("<li>Do 5</li>");

Hier werden Sie den Unterschied bemerken.

Wenn das Ereignis über .click verknüpft wurde, folgt Task 5 dem Klickereignis nicht und wird daher nicht entfernt.

Wenn es über .on mit dem separaten Selektor verknüpft wurde, wird es gehorchen.


2

Um die Ereignisdelegierung zuerst zu verstehen, müssen wir wissen, warum und wann wir die Ereignisdelegierung tatsächlich benötigen oder wollen.

Es mag viele Fälle geben, aber lassen Sie uns zwei große Anwendungsfälle für die Ereignisdelegation diskutieren. 1. Der erste Fall ist, wenn wir ein Element mit vielen untergeordneten Elementen haben, an denen wir interessiert sind. In diesem Fall fügen wir, anstatt allen diesen untergeordneten Elementen einen Ereignishandler hinzuzufügen, ihn einfach dem übergeordneten Element hinzu und bestimmen dann Auf welches untergeordnete Element wurde das Ereignis ausgelöst?

2. Der zweite Anwendungsfall für die Ereignisdelegierung besteht darin, dass ein Ereignishandler an ein Element angehängt werden soll, das sich beim Laden unserer Seite noch nicht im DOM befindet. Das liegt natürlich daran, dass wir einem Ereignishandler, der nicht auf unserer Seite ist, keinen Ereignishandler hinzufügen können, also im Falle eines Verfalls, den wir codieren.

Angenommen, Sie haben eine Liste mit 0, 10 oder 100 Elementen im DOM, wenn Sie Ihre Seite laden, und weitere Elemente warten in Ihrer Hand darauf, in die Liste aufgenommen zu werden. Es gibt also keine Möglichkeit, einen Ereignishandler für zukünftige Elemente anzuhängen, oder diese Elemente werden noch nicht im DOM hinzugefügt, und es können auch viele Elemente vorhanden sein. Daher wäre es nicht sinnvoll, jeweils einen Ereignishandler anzuhängen von ihnen.

Ereignisdelegation

Also gut, um über Eventdelegation zu sprechen, ist das erste Konzept, über das wir tatsächlich sprechen müssen, das Sprudeln von Events.

Ereignisblasen: Ereignisblasen bedeutet, dass, wenn ein Ereignis für ein DOM-Element ausgelöst oder ausgelöst wird, beispielsweise durch Klicken auf unsere Schaltfläche hier im folgenden Bild, genau dasselbe Ereignis auch für alle übergeordneten Elemente ausgelöst wird.

Geben Sie hier die Bildbeschreibung ein

Das Ereignis wird zuerst auf die Schaltfläche ausgelöst, dann aber auch nacheinander auf alle übergeordneten Elemente, sodass es auch auf den Absatz des Abschnitts des Hauptelements und tatsächlich ganz oben in einem DOM-Baum ausgelöst wird bis zum HTML-Element, das die Wurzel ist. Wir sagen also, dass das Ereignis im DOM-Baum in die Luft sprudelt, und deshalb wird es als Sprudeln bezeichnet.

1 2 3 4

Zielelement: Das Element, auf das das Ereignis tatsächlich zum ersten Mal ausgelöst wurde, wird als Zielelement bezeichnet. Das Element, das das Ereignis verursacht hat, wird als Zielelement bezeichnet. In unserem obigen Beispiel hier ist es natürlich die Schaltfläche, auf die geklickt wurde. Der wichtige Teil ist, dass dieses Zielelement als Eigenschaft im Ereignisobjekt gespeichert wird. Dies bedeutet, dass alle übergeordneten Elemente, auf die das Ereignis auch ausgelöst wird, das Zielelement des Ereignisses kennen, also wo das Ereignis zuerst ausgelöst wurde.

Das bringt uns zur Ereignisdelegierung, denn wenn das Ereignis im DOM-Baum sprudelt und wir wissen, wo das Ereignis ausgelöst wurde, können wir einfach einen Ereignishandler an ein übergeordnetes Element anhängen und warten, bis das Ereignis sprudelt, und wir können Machen Sie dann alles, was wir mit unserem Zielelement vorhaben. Diese Technik wird als Ereignisdelegation bezeichnet. In diesem Beispiel hier könnten wir einfach den Ereignishandler zum Hauptelement hinzufügen.

Also gut, die Ereignisdelegation besteht darin, den Ereignishandler nicht für das ursprüngliche Element einzurichten, an dem wir interessiert sind, sondern ihn an ein übergeordnetes Element anzuhängen und das Ereignis dort im Grunde zu erfassen, weil es sprudelt. Wir können dann auf das Element einwirken, an dem wir interessiert sind, indem wir die Zielelement-Eigenschaft verwenden.

Beispiel: Nehmen wir nun an, wir haben zwei Listenelemente auf unserer Seite. Nachdem wir Elemente in dieser Liste programmgesteuert hinzugefügt haben, möchten wir ein oder mehrere Elemente aus ihnen löschen. Mit der Technik der Ereignisdelegation können wir unseren Zweck leicht erreichen.

<div class="body">
    <div class="top">

    </div>
    <div class="bottom">
        <div class="other">
            <!-- other bottom elements -->
        </div>
        <div class="container clearfix">
            <div class="income">
                <h2 class="icome__title">Income</h2>
                <div class="income__list">
                    <!-- list items -->
                </div>
            </div>
            <div class="expenses">
                <h2 class="expenses__title">Expenses</h2>
                <div class="expenses__list">
                    <!-- list items -->
                </div>
            </div>
        </div>
    </div>
</div>

Hinzufügen von Elementen zu dieser Liste:

const DOMstrings={
        type:{
            income:'inc',
            expense:'exp'
        },
        incomeContainer:'.income__list',
        expenseContainer:'.expenses__list',
        container:'.container'
   }


var addListItem = function(obj, type){
        //create html string with the place holder
        var html, element;
        if(type===DOMstrings.type.income){
            element = DOMstrings.incomeContainer
            html = `<div class="item clearfix" id="inc-${obj.id}">
            <div class="item__description">${obj.descripiton}</div>
            <div class="right clearfix">
                <div class="item__value">${obj.value}</div>
                <div class="item__delete">
                    <button class="item__delete--btn"><i class="ion-ios-close-outline"></i></button>
                </div>
            </div>
        </div>`
        }else if (type ===DOMstrings.type.expense){
            element=DOMstrings.expenseContainer;
            html = ` <div class="item clearfix" id="exp-${obj.id}">
            <div class="item__description">${obj.descripiton}</div>
            <div class="right clearfix">
                <div class="item__value">${obj.value}</div>
                <div class="item__percentage">21%</div>
                <div class="item__delete">
                    <button class="item__delete--btn"><i class="ion-ios-close-outline"></i></button>
                </div>
            </div>
        </div>`
        }
        var htmlObject = document.createElement('div');
        htmlObject.innerHTML=html;
        document.querySelector(element).insertAdjacentElement('beforeend', htmlObject);
    }

Elemente löschen:

var ctrlDeleteItem = function(event){
       // var itemId = event.target.parentNode.parentNode.parentNode.parentNode.id;
        var parent = event.target.parentNode;
        var splitId, type, ID;
        while(parent.id===""){
            parent = parent.parentNode
        }
        if(parent.id){
            splitId = parent.id.split('-');
            type = splitId[0];
            ID=parseInt(splitId[1]);
        }

        deleteItem(type, ID);
        deleteListItem(parent.id);
 }

 var deleteItem = function(type, id){
        var ids, index;
        ids = data.allItems[type].map(function(current){
            return current.id;
        });
        index = ids.indexOf(id);
        if(index>-1){
            data.allItems[type].splice(index,1);
        }
    }

  var deleteListItem = function(selectorID){
        var element = document.getElementById(selectorID);
        element.parentNode.removeChild(element);
    }

1

Ein Delegat in C # ähnelt einem Funktionszeiger in C oder C ++. Durch die Verwendung eines Delegaten kann der Programmierer einen Verweis auf eine Methode in einem Delegatenobjekt kapseln. Das Delegatenobjekt kann dann an Code übergeben werden, der die referenzierte Methode aufrufen kann, ohne zur Kompilierungszeit wissen zu müssen, welche Methode aufgerufen wird.

Siehe diesen Link -> http://www.akadia.com/services/dotnet_delegates_and_events.html


5
Ich werde dies nicht ablehnen, da es wahrscheinlich eine korrekte Antwort auf die ursprüngliche Frage war, aber die Frage
bezieht

1

Bei der Ereignisdelegierung werden zwei häufig übersehene Funktionen von JavaScript-Ereignissen verwendet: Ereignisblasen und das Zielelement. Wenn ein Ereignis für ein Element ausgelöst wird, z. B. ein Mausklick auf eine Schaltfläche, wird dasselbe Ereignis auch für alle Vorfahren dieses Elements ausgelöst . Dieser Vorgang wird als Ereignisblasen bezeichnet. Das Ereignis sprudelt vom Ursprungselement zum oberen Rand des DOM-Baums.

Stellen Sie sich eine HTML-Tabelle mit 10 Spalten und 100 Zeilen vor, in der etwas passieren soll, wenn der Benutzer auf eine Tabellenzelle klickt. Zum Beispiel musste ich einmal jede Zelle einer Tabelle dieser Größe beim Klicken bearbeitbar machen. Das Hinzufügen von Ereignishandlern zu jeder der 1000 Zellen wäre ein großes Leistungsproblem und möglicherweise eine Ursache für Speicherverluste beim Absturz des Browsers. Stattdessen würden Sie mithilfe der Ereignisdelegierung nur einen Ereignishandler zum Tabellenelement hinzufügen, das Klickereignis abfangen und bestimmen, auf welche Zelle geklickt wurde.


0
Ereignisdelegation

Hängen Sie einen Ereignis-Listener an ein übergeordnetes Element an, das ausgelöst wird, wenn ein Ereignis für ein untergeordnetes Element auftritt.

Ereignisausbreitung

Wenn ein Ereignis durch das DOM vom untergeordneten zum übergeordneten Element verschoben wird, wird dies als Ereignisausbreitung bezeichnet , da sich das Ereignis ausbreitet oder durch das DOM bewegt.

In diesem Beispiel wird ein Ereignis (onclick) von einer Schaltfläche an den übergeordneten Absatz übergeben.

$(document).ready(function() {

    $(".spoiler span").hide();

    /* add event onclick on parent (.spoiler) and delegate its event to child (button) */
    $(".spoiler").on( "click", "button", function() {
    
        $(".spoiler button").hide();    
    
        $(".spoiler span").show();
    
    } );

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

<p class="spoiler">
    <span>Hello World</span>
    <button>Click Me</button>
</p>

Codepen

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.