Co to jest delegowanie zdarzeń DOM?

202

Czy ktoś może wyjaśnić delegowanie zdarzeń w JavaScript i jak to jest przydatne?

Ksenon
źródło
2
Byłoby miło, gdyby istniał link do podtytułu przydatne źródło informacji na ten temat. Za 6 godzin jest to hit Google w kategorii „delegowanie zdarzeń domowych”. Może to jest przydatny link? Nie jestem do końca pewien: w3.org/TR/DOM-Level-2-Events/events.html
Sean McMillan
A może to: sitepoint.com/blogs/2008/07/23/…
Sean McMillan
7
To jest popularny. Nawet fb faceci prowadzą do tego linku na stronie davidwalsh.name/event-delegate
Sorter
Zobacz javascript.info/event-delegation, która bardzo ci pomoże
Suraj Jain,

Odpowiedzi:

330

Delegowanie zdarzeń DOM to mechanizm reagowania na zdarzenia interfejsu użytkownika za pośrednictwem pojedynczego wspólnego rodzica, a nie każdego dziecka, za pomocą magii „bąbelkowania” zdarzeń (czyli propagacji zdarzeń).

Gdy zdarzenie jest wyzwalane na elemencie, występują następujące zdarzenia :

Zdarzenie jest wysyłane do miejsca docelowego, EventTargeta wykryte tam detektory zdarzeń są uruchamiane. Pęcherzyki zdarzeń wyzwalają następnie wszelkie dodatkowe detektory zdarzeń znalezione przez podążanie EventTargetłańcucha nadrzędnego w górę , sprawdzanie, czy detektory zdarzeń są zarejestrowane w każdym kolejnym EventTarget. Ta propagacja w górę będzie kontynuowana aż do Document.

Tworzenie pęcherzyków zdarzeń stanowi podstawę do delegowania zdarzeń w przeglądarkach. Teraz możesz powiązać moduł obsługi zdarzeń z pojedynczym elementem nadrzędnym, a ten moduł obsługi zostanie wykonany za każdym razem, gdy zdarzenie wystąpi w dowolnym z jego węzłów podrzędnych (i każdego z ich podrzędnych z kolei). To jest delegowanie wydarzeń. Oto przykład tego w praktyce:

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

W tym przykładzie, jeśli klikniesz którykolwiek z <li>węzłów podrzędnych , zobaczysz alert "click!", nawet jeśli nie ma programu obsługi kliknięć związanego z <li>klikniętym. Jeśli związamy się onclick="..."z każdym z nich <li>, uzyskasz ten sam efekt.

Jaka jest więc korzyść?

Wyobraź sobie, że teraz musisz dynamicznie dodawać nowe <li>elementy do powyższej listy za pomocą manipulacji DOM:

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

Bez korzystania z delegowania zdarzeń należy „ponownie powiązać” moduł "onclick"obsługi zdarzeń z nowym <li>elementem, aby działał on tak samo, jak jego rodzeństwo. Dzięki delegowaniu wydarzeń nie musisz nic robić. Po prostu dodaj nowy <li>do listy i gotowe.

Jest to absolutnie fantastyczne dla aplikacji internetowych z modułami obsługi zdarzeń powiązanymi z wieloma elementami, w których nowe elementy są dynamicznie tworzone i / lub usuwane w DOM. Dzięki delegowaniu zdarzeń można znacznie zmniejszyć liczbę powiązań zdarzeń, przenosząc je do wspólnego elementu nadrzędnego, a kod, który dynamicznie tworzy nowe elementy w locie, można oddzielić od logiki wiązania ich procedur obsługi zdarzeń.

Kolejną korzyścią z delegowania zdarzeń jest to, że całkowity ślad pamięci używany przez detektory zdarzeń zmniejsza się (ponieważ zmniejsza się liczba powiązań zdarzeń). Może to nie mieć większego znaczenia w przypadku małych stron, które często się rozładowują (tj. Użytkownik często przechodzi do różnych stron). Ale w przypadku długotrwałych aplikacji może być znaczący. Istnieją pewne naprawdę trudne do wyśledzenia sytuacje, w których elementy usunięte z DOM nadal zajmują pamięć (tj. Przeciekają), a często ta wyciekająca pamięć jest powiązana z powiązaniem zdarzenia. Dzięki delegowaniu wydarzeń możesz niszczyć elementy potomne bez ryzyka zapomnienia o „cofnięciu wiązania” ich detektorów zdarzeń (ponieważ słuchacz jest na przodku). Tego rodzaju wycieki pamięci mogą być następnie powstrzymane (jeśli nie wyeliminowane, co czasem jest cholernie trudne. IE Patrzę na ciebie).

Oto kilka lepszych przykładów kodu delegowania zdarzeń:

Półksiężyc Świeży
źródło
Mam zakaz dostępu przy otwieraniu trzeciego linku Delegowanie zdarzeń bez biblioteki javascript i +1 do ostatniego linku
bugwheels94
Witam, dziękuję za świetne wyjaśnienie. Nadal jednak jestem zdezorientowany co do pewnego szczegółu: sposobu, w jaki rozumiem przepływ zdarzeń drzewa DOM (jak można zobaczyć w 3.1. Wywołanie zdarzenia i przepływ zdarzeń DOM ) obiekt zdarzenia propaguje się, dopóki nie osiągnie elementu docelowego, a następnie pęcherzyków. Jak może dotrzeć do elementów potomnych węzła, jeśli rodzic tego węzła jest celem zdarzenia? np. jak zdarzenie może się przenieść do <li>momentu, w którym powinno się zatrzymać <ul>? Jeśli moje pytanie jest nadal niejasne lub potrzebuje osobnego wątku, chętnie bym się zobowiązał.
Aetos,
@Aetos: > W jaki sposób może dotrzeć do elementów potomnych węzła, jeśli rodzic tego węzła jest celem zdarzenia? Nie mogę, jak rozumiem. Zdarzenie kończy fazę 1 (przechwytywanie) u rodzica celu, wchodzi w fazę 2 (cel) na samym celu, a następnie wchodzi w fazę 3 (bulgotanie) rozpoczynając od rodzica celu. Nigdzie nie dociera do dziecka celu.
Crescent Fresh,
@Crescent Fresh dobrze więc jak to wydarzenie stosuje się do węzła potomnego, jeśli nigdy go nie osiągnie?
Aetos
1
Naprawdę świetna odpowiedź. Dziękujemy za wyjaśnienie delegacji wydarzenia odpowiednimi faktami. Dzięki!
Kshitij Tiwari
30

Delegowanie zdarzeń pozwala uniknąć dodawania detektorów zdarzeń do określonych węzłów; zamiast tego detektor zdarzeń jest dodawany do jednego rodzica. Ten detektor zdarzeń analizuje bąbelkowe zdarzenia, aby znaleźć dopasowanie elementów potomnych.

Przykład JavaScript:

Powiedzmy, że mamy nadrzędny element UL z kilkoma elementami potomnymi:

<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>

Powiedzmy również, że coś musi się wydarzyć po kliknięciu każdego elementu potomnego. Możesz dodać osobny detektor zdarzeń do każdego elementu LI, ale co, jeśli elementy LI są często dodawane i usuwane z listy? Dodawanie i usuwanie detektorów zdarzeń byłoby koszmarem, szczególnie jeśli kod dodawania i usuwania znajduje się w różnych miejscach aplikacji. Lepszym rozwiązaniem jest dodanie detektora zdarzeń do nadrzędnego elementu UL. Ale jeśli dodasz detektor zdarzeń do elementu nadrzędnego, skąd będziesz wiedzieć, który element został kliknięty?

Proste: gdy zdarzenie przechodzi do elementu UL, sprawdzasz właściwość celu obiektu zdarzenia, aby uzyskać odniesienie do faktycznie klikniętego węzła. Oto bardzo podstawowy fragment kodu JavaScript ilustrujący delegowanie zdarzeń:

// 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!");
       }
 });

Zacznij od dodania detektora zdarzeń kliknięcia do elementu nadrzędnego. Po uruchomieniu detektora zdarzeń sprawdź element zdarzenia, aby upewnić się, że jest to typ elementu, na który ma reagować. Jeśli jest to element LI, boom: mamy to, czego potrzebujemy! Jeśli nie chcemy tego elementu, zdarzenie można zignorować. Ten przykład jest dość prosty - UL i LI to proste porównanie. Spróbujmy czegoś trudniejszego. Miejmy rodzicielską DIV z wieloma dziećmi, ale zależy nam tylko na znaczniku A z klasą Klasa CSS:

  // 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

Osama AbuSitta
źródło
1
Sugerowana poprawka: użyj e.classList.contains () zamiast w ostatnim przykładzie: developer.mozilla.org/en-US/docs/Web/API/Element/classList
nc.
7

delegowanie zdarzeń domowych to coś innego niż definicja informatyki.

Odnosi się do obsługi zdarzeń propagujących z wielu elementów, takich jak komórki tabeli, z obiektu nadrzędnego, takiego jak tabela. Może uprościć kod, szczególnie podczas dodawania lub usuwania elementów, i oszczędza trochę pamięci.

Kennebec
źródło
6

Delegowanie to technika polegająca na tym, że obiekt wyraża pewne zachowanie na zewnątrz, ale w rzeczywistości przekazuje odpowiedzialność za wdrożenie tego zachowania na powiązany obiekt. Brzmi to początkowo bardzo podobnie do wzorca proxy, ale służy znacznie innym celom. Delegowanie jest mechanizmem abstrakcyjnym, który centralizuje zachowanie obiektu (metody).

Ogólnie rzecz biorąc: użyj przekazania jako alternatywy dla dziedziczenia. Dziedziczenie jest dobrą strategią, gdy istnieje ścisły związek między obiektem nadrzędnym i podrzędnym, jednak dziedziczenie łączy obiekty bardzo blisko. Często delegowanie jest bardziej elastycznym sposobem wyrażania relacji między klasami.

Ten wzorzec jest również znany jako „łańcuchy proxy”. Delegowanie ma kilka innych wzorców projektowych - od tego zależą stan, strategia i wzorce użytkowników.

Ewan Todd
źródło
Dobre wytłumaczenie. W przykładzie <ul> z kilkoma <li> dziećmi, najwyraźniej <li> to te, które obsługują logikę kliknięcia, ale tak nie jest, ponieważ „przekazują” tę logikę ojcu <ul>
Juanma Menendez
6

Koncepcja delegacji

Jeśli w jednym obiekcie nadrzędnym znajduje się wiele elementów i chcesz obsłużyć na nich zdarzenia - nie wiąż ich z każdym elementem. Zamiast tego powiąż pojedynczy moduł obsługi z rodzicem i pobierz dziecko z event.target. Ta strona zawiera przydatne informacje na temat wdrażania delegowania zdarzeń. http://javascript.info/tutorial/event-delegation

Joseph
źródło
6

Delegowanie zdarzeń obsługuje zdarzenie, które się bańka za pomocą procedury obsługi zdarzeń na elemencie kontenera, ale aktywuje zachowanie procedury obsługi zdarzeń, jeśli zdarzenie miało miejsce na elemencie w kontenerze, który pasuje do danego warunku. Może to uprościć obsługę zdarzeń na elementach w kontenerze.

Załóżmy na przykład, że chcesz obsłużyć kliknięcie dowolnej komórki tabeli w dużym stole. Państwo mogli napisać pętlę podłączyć do obsługi kliknij do każdej komórki ... czy można podłączyć do obsługi kliknij na delegacji tabeli i użyć zdarzenia wyzwolić go tylko do komórek tabeli (a nie nagłówki tabel lub spacje w ciągu wiersz wokół komórek itp.).

Jest to również przydatne, gdy zamierzasz dodawać i usuwać elementy z kontenera, ponieważ nie musisz się martwić o dodawanie i usuwanie procedur obsługi zdarzeń na tych elementach; wystarczy zaczepić zdarzenie na pojemniku i obsłużyć zdarzenie, gdy się pęcherzykuje.

Oto prosty przykład (celowo szczegółowe, aby umożliwić wbudowane wyjaśnienie): Obsługa kliknięcia dowolnego tdelementu w tabeli kontenera:

// 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>

Zanim przejdziemy do szczegółów, przypomnijmy sobie, jak działają zdarzenia DOM.

Zdarzenia DOM są wysyłane z dokumentu do elementu docelowego ( faza przechwytywania ), a następnie bąbelkowe z elementu docelowego z powrotem do dokumentu ( faza bąbelkowania ). Ta grafika w starej specyfikacji zdarzeń DOM3 (teraz zastąpiona, ale grafika nadal ważna) pokazuje ją naprawdę dobrze:

wprowadź opis zdjęcia tutaj

Nie wszystkie wydarzenia bańki, ale większość, w tym click.

Komentarze w powyższym przykładzie kodu opisują, jak to działa. matchessprawdza, czy element pasuje do selektora CSS, ale oczywiście możesz sprawdzić, czy coś spełnia twoje kryteria w inny sposób, jeśli nie chcesz używać selektora CSS.

Że kod jest napisany zawołać poszczególne kroki --long, ale niejasno nowoczesnych przeglądarek (IE, a także w przypadku korzystania z PolyFill), można wykorzystać closesti containszamiast pętli:

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");
}

Przykład na żywo:

closestsprawdza element, który go wywołujesz, aby sprawdzić, czy pasuje do podanego selektora CSS, a jeśli tak, zwraca ten sam element; jeśli nie, sprawdza element nadrzędny, aby sprawdzić, czy pasuje, i zwraca element nadrzędny, jeśli tak; jeśli nie, sprawdza rodzica rodzica itp. Znajduje więc „najbliższy” element na liście przodków pasujący do selektora. Ponieważ może to minąć element kontenera, powyższy kod używa containsdo sprawdzenia, czy jeśli znaleziono pasujący element, znajduje się on w kontenerze - ponieważ podpinając zdarzenie do kontenera, wskazałeś, że chcesz obsługiwać tylko elementy w tym kontenerze .

Wracając do naszego przykładu tabeli, oznacza to, że jeśli masz tabelę w komórce tabeli, nie będzie pasować do komórki tabeli zawierającej tabelę:

TJ Crowder
źródło
3

Zasadniczo polega to na powiązaniu z elementem. .clickma zastosowanie do bieżącego DOM, a .on(przy użyciu delegowania) będzie nadal obowiązywał dla nowych elementów dodanych do DOM po skojarzeniu zdarzenia.

Którego lepiej użyć, powiedziałbym, że zależy to od przypadku.

Przykład:

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

. Kliknij Wydarzenie:

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

Zdarzenie .on:

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

Zwróć uwagę, że wybrałem selektor w .on. Wyjaśnię dlaczego.

Załóżmy, że po tym skojarzeniu wykonajmy następujące czynności:

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

Tutaj zauważysz różnicę.

Jeśli zdarzenie zostało powiązane za pomocą .click, zadanie 5 nie będzie przestrzegać zdarzenia kliknięcia, a więc nie zostanie usunięte.

Jeśli został powiązany z .on, z selektorem oddzielnym, będzie posłuszny.

Lucas
źródło
2

Aby najpierw zrozumieć delegację wydarzeń, musimy wiedzieć, dlaczego i kiedy faktycznie potrzebujemy lub chcemy delegacji wydarzeń.

Może być wiele przypadków, ale omówmy dwa duże przypadki użycia do delegowania zdarzeń. 1. Pierwszy przypadek ma miejsce, gdy mamy element z dużą ilością elementów potomnych, którymi jesteśmy zainteresowani. W tym przypadku zamiast dodawać moduł obsługi zdarzeń do wszystkich tych elementów potomnych, po prostu dodajemy go do elementu nadrzędnego, a następnie określamy na który element potomny uruchomiono zdarzenie.

2. Drugi przypadek użycia dla delegowania zdarzeń ma miejsce, gdy chcemy, aby procedura obsługi zdarzeń była dołączona do elementu, który nie jest jeszcze w DOM, gdy nasza strona jest ładowana. To oczywiście dlatego, że nie możemy dodać modułu obsługi zdarzeń do czegoś, co nie znajduje się na naszej stronie, więc w przypadku zaniechania, które kodujemy.

Załóżmy, że masz listę 0, 10 lub 100 elementów w DOM podczas wczytywania strony, a więcej elementów czeka na Ciebie, aby dodać je na liście. Nie ma więc sposobu na dołączenie modułu obsługi zdarzeń dla przyszłych elementów lub te elementy nie zostały jeszcze dodane do DOM, a także może być wiele elementów, więc nie byłoby przydatne, aby do każdego z nich był dołączony jeden moduł obsługi zdarzeń z nich.

Delegacja wydarzeń

W porządku, więc aby porozmawiać o delegowaniu wydarzeń, pierwszą koncepcją, o której naprawdę musimy porozmawiać, jest propagacja wydarzeń.

Bubbing zdarzeń: Bubbing zdarzeń oznacza, że ​​gdy zdarzenie jest uruchamiane lub wyzwalane na jakimś elemencie DOM, na przykład poprzez kliknięcie naszego przycisku na poniższym obrazie, wówczas to samo zdarzenie jest wywoływane również na wszystkich elementach nadrzędnych.

wprowadź opis zdjęcia tutaj

Zdarzenie jest najpierw uruchamiane na przycisku, ale następnie będzie również uruchamiane na wszystkich elementach nadrzędnych pojedynczo, więc będzie również odpalane w akapicie do sekcji głównego elementu i faktycznie aż do góry w drzewie DOM aż do elementu HTML, który jest rootem. Mówimy więc, że wydarzenie pęka w drzewie DOM i dlatego nazywa się to bulgotaniem.

1 2) 3) 4

Element docelowy: Element, w którym zdarzenie zostało po raz pierwszy uruchomione, nazywał się elementem docelowym, więc element, który spowodował zdarzenie, nazywany jest elementem docelowym. W naszym powyższym przykładzie jest to oczywiście przycisk, który został kliknięty. Ważną częścią jest to, że ten element docelowy jest przechowywany jako właściwość w obiekcie zdarzenia. Oznacza to, że wszystkie elementy nadrzędne, na których również zostanie uruchomione zdarzenie, będą znać element docelowy zdarzenia, a więc miejsce, w którym zdarzenie zostało po raz pierwszy uruchomione.

To prowadzi nas do delegowania zdarzeń, ponieważ jeśli wydarzenie pęka w drzewie DOM, a jeśli wiemy, gdzie zostało ono uruchomione, możemy po prostu dołączyć moduł obsługi zdarzenia do elementu nadrzędnego i poczekać, aż zdarzenie się pojawi. następnie zrób wszystko, co zamierzaliśmy zrobić z naszym elementem docelowym. Ta technika nazywa się delegowaniem wydarzeń. W tym przykładzie moglibyśmy po prostu dodać moduł obsługi zdarzeń do głównego elementu.

W porządku, więc ponownie delegowanie zdarzeń nie polega na ustawianiu procedury obsługi zdarzenia na oryginalnym elemencie, który nas interesuje, ale na dołączeniu go do elementu nadrzędnego i, w zasadzie, przechwyceniu zdarzenia, ponieważ pęka. Następnie możemy działać na elemencie, który jest zainteresowany wykorzystaniem właściwości elementu docelowego.

Przykład: Załóżmy teraz, że mamy dwa elementy listy na naszej stronie, po programowym dodaniu elementów z tych list chcemy usunąć jeden lub więcej elementów z nich. Korzystając z techniki delegowania wydarzeń, możemy łatwo osiągnąć nasz cel.

<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>

Dodawanie elementów na tych listach:

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);
    }

Usuń elementy:

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);
    }
Lord
źródło
1

Delegat w C # jest podobny do wskaźnika funkcji w C lub C ++. Użycie delegata pozwala programiście enkapsulować odwołanie do metody wewnątrz obiektu delegowanego. Obiekt delegowany może być następnie przekazany do kodu, który może wywołać metodę, do której istnieje odwołanie, bez konieczności informowania w czasie kompilacji, która metoda zostanie wywołana.

Zobacz ten link -> http://www.akadia.com/services/dotnet_delegates_and_events.html

Bhaskar
źródło
5
Nie będę głosować nad tym, ponieważ prawdopodobnie była to prawidłowa odpowiedź na pierwotne pytanie, ale pytanie dotyczy teraz delegacji zdarzeń DOM i Javascript
iandotkelly
1

Delegowanie zdarzeń korzysta z dwóch często pomijanych cech zdarzeń JavaScript: propagacji zdarzeń i elementu docelowego. Gdy zdarzenie jest wyzwalane na elemencie, na przykład kliknięcie przycisku myszy, to samo zdarzenie jest również wywoływane u wszystkich przodków tego elementu . Ten proces jest znany jako propagowanie zdarzeń; zdarzenie przechodzi w górę od elementu źródłowego na szczyt drzewa DOM.

Wyobraź sobie tabelę HTML z 10 kolumnami i 100 wierszami, w których chcesz, aby coś się wydarzyło, gdy użytkownik kliknie komórkę tabeli. Na przykład kiedyś musiałem umożliwić edytowanie każdej komórki tabeli tego rozmiaru po kliknięciu. Dodanie procedur obsługi zdarzeń do każdej z 1000 komórek stanowiłoby poważny problem z wydajnością i potencjalnie źródłem wycieków pamięci powodujących awarie przeglądarki. Zamiast tego, korzystając z delegowania zdarzeń, należy dodać tylko jeden moduł obsługi zdarzeń do elementu tabeli, przechwycić zdarzenie click i ustalić, która komórka została kliknięta.

Priti jha
źródło
0
Delegacja wydarzeń

Dołącz detektor zdarzeń do elementu nadrzędnego, który jest uruchamiany, gdy wystąpi zdarzenie w elemencie potomnym.

Propagacja wydarzeń

Kiedy zdarzenie przenosi się przez DOM z elementu podrzędnego do elementu nadrzędnego, nazywa się to Propagacją zdarzenia , ponieważ zdarzenie jest propagowane lub przechodzi przez DOM.

W tym przykładzie zdarzenie (kliknięcie) z przycisku jest przekazywane do akapitu nadrzędnego.

$(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

antylopa
źródło