DOM
Wydarzenia
Szukaj…
Parametry
Parametr | Opis |
---|---|
rodzaj | String określa nazwę zdarzenia, którego należy słuchać. |
słuchacz | Function uruchamia się, gdy wystąpi zdarzenie. |
opcje | Boolean aby ustawić przechwytywanie, jeśli Object można ustawić na nim następujące właściwości, należy zauważyć, że opcja obiektu jest słabo obsługiwana. |
1. przechwytywanie | Wartość logiczna wskazująca, że zdarzenia tego typu będą wysyłane do zarejestrowanego detektora przed wysłaniem do dowolnego elementu EventTarget pod nim w drzewie DOM. |
2. raz | Wartość logiczna wskazująca, że detektor powinien zostać wywołany co najwyżej raz po dodaniu. Jeśli jest to prawda, detektor zostanie automatycznie usunięty po jego wywołaniu. |
3. pasywny | Wartość logiczna wskazująca, że detektor nigdy nie wywoła funkcji preventDefault (). Jeśli tak, agent użytkownika powinien go zignorować i wygenerować ostrzeżenie konsoli. |
Uwagi
Geneza wydarzeń
Zdarzenia nie zaczynają się od momentu, w którym je wywołujesz (na przykład przycisk).
Zamiast
Dotyka każdego elementu na swojej drodze i informuje każdy element, że ma miejsce wydarzenie. Wydarzenia wracają również po dotarciu do miejsca docelowego, ponownie informując elementy o jego wystąpieniu.
Capturing & Bubbling
Jak się dowiedzieliśmy, zdarzenia zaczynają się od szczytu drzewa DOM, informują każdy węzeł na ścieżce do miejsca docelowego, a następnie wracają w górę, gdy docierają do miejsca docelowego, informując również każdy element, który dotyka na swojej drodze, o jego wystąpieniu.
Zdarzenia schodzące z drzewa DOM znajdują się w fazie przechwytywania , zdarzenia wychodzące z drzewa DOM znajdują się w fazie bulgotania .
Domyślnie zdarzenia są nasłuchiwane w fazie propagacji. Aby to zmienić, możesz określić, w której fazie zdarzenie będzie nasłuchiwane, określając trzeci parametr w funkcji addEventListener. (przykład kodu w sekcji przechwytywania )
Wprowadzenie
Definicja:
W informatyce zdarzenie to czynność lub zdarzenie rozpoznawane przez oprogramowanie, które może być obsługiwane przez oprogramowanie. Zdarzenia komputerowe mogą być generowane lub wyzwalane przez system, przez użytkownika lub w inny sposób. Źródło definicji
Zdarzenia HTML to „rzeczy”, które przytrafiają się elementom HTML. JavaScript może „reagować” na te zdarzenia. za pośrednictwem Event Listeners
. Ponadto zdarzenia niestandardowe mogą być wyzwalane za pomocą dispatchEvent
. Ale to tylko wstęp, więc zacznijmy!
Podstawowy detektor zdarzeń
Aby nasłuchiwać zdarzeń, wywołujesztarget.addEventListener(type, listener);
function loadImage() {
console.log('image code here!');
}
var myButton = document.querySelector('#my-button');
myButton.addEventListener('click', loadImage);
Spowoduje to uruchomienie loadImage za każdym razem my-button
kliknięty zostanie my-button
.
Detektory zdarzeń można podłączyć do dowolnego węzła w drzewie DOM. aby zobaczyć pełną listę wszystkich zdarzeń natywnie wyzwalanych w przeglądarce: przejdź tutaj link MDN, aby uzyskać pełną listę zdarzeń
Usuwanie detektorów zdarzeń
Metoda removeEventListener () usuwa procedury obsługi zdarzeń, które zostały dołączone za pomocą metody addEventListener ():
element.removeEventListener("mousemove", myFunction);
Wszystko (nazwa zdarzenia, funkcja i opcje) w removeEventListener
musi pasować do zestawu ustawionego podczas dodawania detektora zdarzeń do elementu.
.bind z removeListener
użycie .bind
na funkcji podczas dodawania detektora zdarzeń zapobiegnie usunięciu funkcji, aby faktycznie usunąć eventListener, który możesz napisać:
function onEvent() {
console.log(this.name);
}
var bindingOnEvent = onEvent.bind(this);
document.addEventListener('click', bindingOnEvent);
...
document.removeEventListener('click', bindingOnEvent);
słuchaj wydarzenia tylko raz
Ażonce
opcja jest szeroko wspierany, musimy ręcznie usunąć nawet słuchacza, gdy zdarzenie jest wywoływane po raz pierwszy. Ten mały pomocnik pomoże nam to osiągnąć:
Object.prototype.listenOnce = Object.prototype.listenOnce ||
function listenOnce(eventName, eventHandler, options) {
var target = this;
target.addEventListener(eventName, function(e) {
eventHandler(e);
target.removeEventListener(eventName, eventHandler, options);
}, options);
}
var target = document.querySelector('#parent');
target.listenOnce("click", clickFunction, false);
* Nie jest najlepszą praktyką dołączanie funkcji do prototypu Object, dlatego możesz usunąć pierwszą linię tego kodu i dodać do niego cel jako pierwszy parametr.
Oczekiwanie na załadowanie dokumentu
Jednym z najczęściej używanych zdarzeń jest oczekiwanie na załadowanie dokumentu, w tym zarówno plików skryptów, jak i obrazów. Do tego celu służy zdarzenie load
document
.
document.addEventListener('load', function() {
console.log("Everything has now loaded!");
});
Czasami próbujesz uzyskać dostęp do obiektu DOM przed jego załadowaniem, co powoduje zerowe wskaźniki. Naprawdę trudno je debugować. Aby tego uniknąć, użyj zamiast tego zdarzenia DOMContentLoaded
document
. DOMContentLoaded
zapewnia, że treść HTML została załadowana i zainicjowana bez oczekiwania na inne zasoby zewnętrzne.
document.addEventListener('DOMContentLoaded', function() {
console.log("The document contents are now available!");
});
Obiekt zdarzenia
Aby uzyskać dostęp do obiektu zdarzenia, event
parametr zdarzenia do funkcji wywołania zwrotnego detektora zdarzeń:
var foo = document.getElementById("foo");
foo.addEventListener("click", onClick);
function onClick(event) {
// the `event` parameter is the event object
// e.g. `event.type` would be "click" in this case
};
e.stopPropagation ();
HTML:<div id="parent">
<div id="child"></div>
</div>
JavaScript:
var parent = document.querySelector('#parent');
var child = document.querySelector('#child');
child.addEventListener('click', function(e) {
e.stopPropagation();
alert('child clicked!');
});
parent.addEventListener('click', function(e) {
alert('parent clicked!');
});
ponieważ dziecko zatrzymuje propagację zdarzeń, a zdarzenia są nasłuchiwane podczas fazy propagacji, kliknięcie dziecka uruchomi tylko dziecko. bez zatrzymania propagacji oba zdarzenia zostaną uruchomione.
e.preventDefault ();
Metoda event.preventDefault()
zatrzymuje działanie domyślne elementu.
Na przykład:
- Zapobiegaj przesyłaniu formularza przez przycisk przesyłania
- Uniemożliwiaj linkowi śledzenie adresu URL
var allAnchorTags = document.querySelector('a');
allAnchorTags.addEventListener('click', function(e){
e.preventDefault();
console.log('anchor tags are useless now! *evil laugh*');
});
e.target vs e.currentTarget
e.currentTarget Identyfikuje bieżący cel zdarzenia, gdy zdarzenie przechodzi przez DOM. Zawsze odnosi się do elementu, do którego została dołączona procedura obsługi zdarzeń, w przeciwieństwie do event.target, który identyfikuje element, w którym zdarzenie miało miejsce.
innymi słowy
e.target
zwróci to, co wyzwala dyspozytora zdarzeń
e.currentTarget
zwróci to, do czego przypisałeś swojego słuchacza.
HTML:
<body>
<button id="my-button"></button>
</body>
JavaScript:
var body = document.body;
body.addEventListener( 'click', function(e) {
console.log('e.target', e.target);
console.log('e.currentTarget', e.currentTarget);
});
jeśli klikniesz my-button
,
- e.target będzie
my-button
- e.currentTarget będzie
body
Bulgotanie i przechwytywanie zdarzeń
Zdarzenia uruchamiane na elementach DOM nie wpływają tylko na element, na który są kierowane. Każdy z przodków celu w DOM może również mieć szansę zareagować na zdarzenie. Rozważ następujący dokument:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<p id="paragraph">
<span id="text">Hello World</span>
</p>
</body>
</html>
Jeśli po prostu dodamy detektory do każdego elementu bez żadnych opcji, uruchom kliknięcie zakresu ...
document.body.addEventListener('click', function(event) {
console.log("Body clicked!");
});
window.paragraph.addEventListener('click', function(event) {
console.log("Paragraph clicked!");
});
window.text.addEventListener('click', function(event) {
console.log("Text clicked!");
});
window.text.click();
... to wydarzenie będzie rozchodzić się przez każdego przodka, wyzwalając każdy moduł obsługi kliknięć po drodze:
Text clicked!
Paragraph clicked!
Body clicked!
Jeśli chcesz, aby któryś z twoich programów obsługi zatrzymywał zdarzenie w wyzwalaniu kolejnych procedur, może wywołać event.stopPropagation()
. Na przykład, jeśli zastąpimy nasz drugi moduł obsługi zdarzeń tym:
window.paragraph.addEventListener('click', function(event) {
console.log("Paragraph clicked, and that's it!");
event.stopPropagation();
});
Chcielibyśmy zobaczyć następujące wyjście z body
„s click
obsługi nigdy wywołane:
Text clicked!
Paragraph clicked, and that's it!
Na koniec mamy opcję dodania detektorów zdarzeń, które wyzwalają się podczas „ przechwytywania ” zamiast bąbelkowania. Zanim zdarzenie przepłynie od elementu przez jego przodków, najpierw jest „przechwytywane” aż do elementu przez jego przodków. Przechwytywanie detektora jest dodawane przez podanie wartości true
lub {capture: true}
jako opcjonalnego trzeciego argumentu parametru addEventListener
. Jeśli dodamy następujące obiekty nasłuchujące do naszego pierwszego przykładu powyżej:
document.body.addEventListener('click', function(event) {
console.log("Body click captured!");
}, true);
window.paragraph.addEventListener('click', function(event) {
console.log("Paragraph click captured!");
}, true);
window.text.addEventListener('click', function(event) {
console.log("Text click captured!");
}, true);
Otrzymamy następujące dane wyjściowe:
Body click captured!
Paragraph click captured!
Text click captured!
Text clicked!
Paragraph clicked!
Body clicked!
Domyślnie zdarzenia są nasłuchiwane w fazie propagacji. Aby to zmienić, możesz określić, w której fazie zdarzenie będzie nasłuchiwane, określając trzeci parametr w funkcji addEventListener. (Aby dowiedzieć się więcej na temat przechwytywania i propagacji, sprawdź uwagi )
element.addEventListener(eventName, eventHandler, useCapture)
useCapture: true
oznacza nasłuchiwanie zdarzenia, gdy idzie ono w dół po drzewie DOM. false
oznacza, że zdarzenie nasłuchuje podczas przechodzenia przez drzewo DOM.
window.addEventListener("click", function(){alert('1: on bubble')}, false);
window.addEventListener("click", function(){alert('2: on capture')}, true);
Alerty pojawią się w następującej kolejności:
- 2: przy przechwytywaniu
- 1: na bańce
Rzeczywiste przypadki użycia
Zdarzenie przechwytywania zostanie wysłane przed zdarzeniem bąbelkowym, dlatego możesz upewnić się, że zdarzenie zostanie najpierw odsłuchane, jeśli odsłuchasz je w fazie przechwytywania.
jeśli nasłuchujesz zdarzenia kliknięcia na elemencie nadrzędnym, a innego na jego elemencie podrzędnym, możesz najpierw słuchać elementu podrzędnego lub elementu nadrzędnego, w zależności od zmiany parametru useCapture.
w bulgotaniu zdarzenie potomne jest wywoływane jako pierwsze, w przechwytywaniu, najpierw jako rodzic
HTML:
<div id="parent">
<div id="child"></div>
</div>
JavaScript:
child.addEventListener('click', function(e) {
alert('child clicked!');
});
parent.addEventListener('click', function(e) {
alert('parent clicked!');
}, true);
Ustawienie wartości true dla nadrzędnego zdarzenia eventListener spowoduje najpierw uruchomienie nasłuchiwania nadrzędnego.
W połączeniu z e.stopPropagation () możesz zapobiec wyzwalaniu zdarzenia przez detektor zdarzeń potomnych / lub element nadrzędny. (więcej na ten temat w następnym przykładzie)
Delegacja wydarzeń
Delegowanie zdarzeń to proces, który pozwala nam unikać dodawania detektorów zdarzeń do określonych węzłów; zamiast tego detektor zdarzeń jest dodawany do węzła nadrzędnego. Mechanizm ten wykorzystuje propagację / propagację zdarzeń do obsługi zdarzenia na elemencie / węźle wyższego poziomu w DOM zamiast używania elementu, na podstawie którego zdarzenie zostało utworzone. Na przykład uważamy, że musimy dodać zdarzenia dla następujących elementów listy:
<ul id="container">
<li id="item-1" class="new">Item 1</li>
<li id="item-2">Item 2</li>
<li id="item-3">Item 3</li>
</ul>
Musimy dodać procedury obsługi click
i zasadniczo możemy dodawać detektory do każdego elementu za pomocą pętli, ale wyobraźmy sobie, że chcemy dodawać elementy dynamicznie. Tak więc rejestrujemy wszystkie procedury obsługi zdarzeń, gdy DOM jest ładowany, a po zainicjowaniu DOM i zarejestrowaniu wszystkich procedur obsługi zdarzeń dla każdego elementu, nowo wstawiony element do powyższej UL
nie zareaguje na kliknięcie, ponieważ ten element nie był obecny w DOM kiedy zarejestrujemy detektory kliknięć.
Aby więc rozwiązać ten problem, możemy wykorzystać delegację wydarzeń. Co oznacza, że zamiast rejestrować detektory osobno dla każdego elementu li
, możemy powiązać detektor zdarzeń z jego nadrzędnym elementem UL
, na przykład:
document.getElementById("container").addEventListener("click", function(e) {
console.log("List item " e.target.id, " was clicked!");
});
Ponieważ zdarzenie domyślnie się propaguje (bąbelki w górę), wówczas kliknięcie dowolnego elementu LI
spowoduje, że element UL
również uruchomi to samo zdarzenie. W tym przypadku możemy użyć parametru e
w funkcji, która jest faktycznie obiektem zdarzenia i przenosi pomocne informacje o zdarzeniu, w tym element oryginalny, który zainicjował zdarzenie. Na przykład możemy użyć czegoś takiego:
document.getElementById("container").addEventListener("click", function(e) {
// If UL itself then no action is require
if(e.target.nodeName == 'UL') return false;
if(e.target.classList.contains('new')) {
console.log("List item " e.target.id, " was clicked and it's new!");
}
});
Jest więc oczywiste, że e
(Event Object) pozwala nam zbadać element źródłowy (e.target) i możemy łatwo wstrzykiwać nowe elementy do UL
po załadowaniu DOM, a jedyna delegowana obsługa zdarzeń obsłuży wszystkie zdarzenia click w nadrzędnym UL
który również zajmuje mniej pamięci, ponieważ zadeklarowaliśmy tylko jedną funkcję dla wszystkich elementów.
Wyzwalanie niestandardowych zdarzeń
Interfejs API CustomEvent umożliwia programistom tworzenie niestandardowych zdarzeń i wyzwalanie ich w węzłach DOM, przesyłając po drodze dane.
event = new CustomEvent(typeArg, customEventInit);
typeArg - DOMString reprezentujący nazwę zdarzenia.
customEventInit - to parametry opcjonalne (które zostaną przekazane jako e
w poniższym przykładzie).
Możesz dołączyć eventListeners
do document
lub dowolnego elementu HTML.
Po dodaniu niestandardowego zdarzenia i powiązaniu go z elementem (lub dokumentem) można ręcznie uruchomić je z javascript.
document.addEventListener("event-name", function(e) {
console.log(e.detail); // logs custom object passed from the event.
});
var event = new CustomEvent("event-name", { "param-name": "param-value" });
document.dispatchEvent(event);