Het afhandelen van gebeurtenissen is nog een van die grote redenen om jQuery te gebruiken. Er zijn enkele verschillen tussen browsers in hoe te doen, die jQuery normaliseert in één eenvoudige API, terwijl enkele best practices worden afgedwongen.
Er is in wezen één methode die u moet kennen: .on()
- het werkt als volgt:
$("button").on("click", function() ( // do something ));
Hier geven we de .on()
methode slechts twee parameters. De naam van de gebeurtenis ("klik") en een functie die moet worden uitgevoerd wanneer die gebeurtenis plaatsvindt op een van de elementen in die selectie. Leest redelijk netjes, nietwaar?
Mensen met een aantal eerdere jQuery ervaring misschien vertrouwd met andere bindende methoden zoals .bind()
, .live()
of .delegate()
. Maak je daar geen zorgen meer over, de moderne jQuery heeft ze allemaal gecombineerd, .on()
wat altijd de beste praktijken doet.
Bij het binden van een gebeurtenis zoals we hierboven hebben gedaan, kunt u (en het is meestal slim om) een parameternaam in de functie op te nemen. Die parameter is "het gebeurtenisobject" binnen de functie:
$("button").on("click", function(event) ( // event => "the event object" ));
Via dat gebeurtenisobject krijg je veel informatie. Je bent er al een beetje bekend mee, want we hebben het gewend aan .preventDefault()
en .stopPropagation()
. Maar er is ook veel andere directe informatie in dat object. Dingen zoals wat voor soort gebeurtenis het was (in het geval dat meerdere gebeurtenissen dezelfde functie activeren), wanneer het plaatsvond, waar het plaatsvond (coördinaten, indien van toepassing), op welk element het gebeurde en nog veel meer. Het is de moeite waard om het gebeurtenisobject regelmatig te inspecteren tijdens het coderen.
Er is een concept van evenementdelegatie dat buitengewoon belangrijk is bij het werken met evenementen. Het is een zeer slimme, moderne best practice. Het bevat het idee van reikwijdte.
Een traditionele manier om na te denken over het binden van gebeurtenissen is als "alle knoppen op de pagina zoeken en er een klikgebeurtenis aan binden". Dat werkt natuurlijk, maar het is:
- Niet erg efficiënt
- Breekbaar
Niet efficiënt omdat je JavaScript onmiddellijk dwingt om al die knopelementen te vinden, terwijl je met delegatie misschien slechts één gemakkelijker te vinden element zou kunnen vinden.
Breekbaar, want als er meer knoppen aan de pagina worden toegevoegd, hebben ze de boot al gemist op de binding en moeten ze opnieuw worden gebonden.
Met gebeurtenisdelegatie zou u die klikgebeurtenis aan een element binden dat hoger in de DOM-structuur staat dan de knoppen die ze allemaal bevatten. Misschien een
ergens, misschien het document
zelf. Wanneer u de klikgebeurtenis aan dat hogere element koppelt, geeft u aan dat u nog steeds alleen geïnteresseerd bent in klikken die op knoppen hebben plaatsgevonden. Als er vervolgens op een knop wordt geklikt, wordt die klik uiteindelijk geactiveerd op het hogere element, vanwege de aard van het bubbelen van gebeurtenissen. Maar het gebeurtenisobject zal weten of de oorspronkelijke klik op een knop heeft plaatsgevonden of niet, en de functie die u bij die gebeurtenis hebt ingesteld, wordt geactiveerd of niet, wetende die informatie.
In deze screencast laten we dat als volgt zien:
$("#scope").on("click", "textarea", function(event) ( // Do stuff! console.log(event); ));
Stel je nu voor dat we daar nog een aan zouden toevoegen
. We hoeven geen gebeurtenissen opnieuw te binden, omdat de gebeurtenis nog steeds gelukkig is gebonden aan de reikwijdte en gebeurtenissen nog steeds zullen opborrelen vanuit het nieuw toegevoegde tekstgebied. Dit is vooral handig in webapp-omgevingen waar u regelmatig nieuwe elementen aan de pagina toevoegt.
Een ander goed ding om te weten over jQuery-gebeurtenisbinding is dat ze elkaar niet uitsluiten. Als u nog een klik-handler toevoegt aan precies hetzelfde element dat er al een heeft, wordt er gewoon nog een toegevoegd. U overschrijft de vorige niet. jQuery behandelt dit gewoon redelijk gracieus voor u. U kunt ze altijd ongedaan maken als u inderdaad een eerder gebonden functie wilt opheffen.
Als het exact dezelfde gebeurtenis is, is het de moeite waard om te weten dat u de gebeurtenissen een naamruimte moet geven om een specifieke gebeurtenis te ontkoppelen en niet de andere. Dat gebeurt door een punt in de naam van het evenement te gebruiken, zoals click.namespace
.
$("#scope").on("click.one", "textarea", function(event) ( )); $("#scope").on("click.two", "textarea", function(event) ( )); // Just remove the first $("#scope").off("click.one", "textarea");
.off()
, zoals we het nog niet eerder hebben genoemd, is hoe je evenementen loskoppelt.
Er zijn veel mogelijke DOM-evenementen. Klikken is de grote belangrijkste voor de hand liggende, maar er is dubbelklikken, muis invoeren en muis verlaten, keydown en keyup, specifieke vormen zoals vervaging en verandering, en nog veel meer. Als u geïnteresseerd bent in de volledige lijst, kunt u er een als deze krijgen.
U kunt op de volgende manier meerdere gebeurtenissen tegelijkertijd binden:
$("#scope").on("keydown keyup", "textarea", function(event) ( console.log(event.keyCode); ));
Er zijn enkele omstandigheden waarin u wacht tot een gebeurtenis plaatsvindt, maar als dat eenmaal gebeurt, geeft u er niets meer om of wilt u de functie waaraan u gebonden was, niet meer afvuren. Dat is waar de .one()
functie over gaat. Een standaard use-case daarvoor is een knop voor het verzenden van een formulier (als u met Ajax werkt of wat dan ook). Waarschijnlijk wilt u die verzendknop in wezen uitschakelen nadat ze erop hebben gedrukt, totdat u die informatie kunt verwerken en hen de juiste feedback kunt geven. Dat is natuurlijk niet de enige use case, maar houd daar rekening mee. .one()
== slechts één keer.