jQuery
evenemang
Sök…
Anmärkningar
jQuery hanterar internt händelser via addEventListener- funktionen. Detta betyder att det är helt lagligt att ha mer än en funktion bunden till samma händelse för samma DOM-element.
Bifoga och ta bort eventhanterare
Fäst en evenemangshanterare
Sedan version 1.7 har jQuery händelsens API .on()
. På så sätt kan alla javascript-händelser eller anpassade händelser vara bundna på det nuvarande valda jQuery-elementet. Det finns genvägar som .click()
, men .on()
ger dig fler alternativ.
html
<button id="foo">bar</button>
jQuery
$( "#foo" ).on( "click", function() {
console.log( $( this ).text() ); //bar
});
Lossa en evenemangshanterare
Naturligtvis har du också möjligheten att ta bort händelser från dina jQuery-objekt. Du gör det genom att använda .off( events [, selector ] [, handler ] )
.
html
<button id="hello">hello</button>
jQuery
$('#hello').on('click', function(){
console.log('hello world!');
$(this).off();
});
När du klickar på knappen $(this)
hänvisar det till det aktuella jQuery-objektet och tar bort alla bifogade händelseshanterare från det. Du kan också ange vilken händelseshanterare som ska tas bort.
jQuery
$('#hello').on('click', function(){
console.log('hello world!');
$(this).off('click');
});
$('#hello').on('mouseenter', function(){
console.log('you are about to click');
});
I detta fall mouseenter
fortfarande efter att ha klickat.
Delegerade händelser
Låt oss börja med exempel. Här är ett mycket enkelt exempel på HTML.
Exempel HTML
<html>
<head>
</head>
<body>
<ul>
<li>
<a href="some_url/">Link 1</a>
</li>
<li>
<a href="some_url/">Link 2</a>
</li>
<li>
<a href="some_url/">Link 3</a>
</li>
</ul>
</body>
</html>
Problemet
I det här exemplet vill vi lägga till en händelse lyssnare till alla <a>
element. Problemet är att listan i det här exemplet är dynamisk. <li>
element läggs till och tas bort när tiden går. Men sidan uppdateras inte mellan ändringar, vilket skulle göra det möjligt för oss att använda enkla lyssnarhändelselister till länkobjekten (dvs. $('a').click()
).
Problemet vi har är hur man lägger till händelser till <a>
-elementen som kommer och går.
Bakgrundsinformation - Eventförökning
Delegerade händelser är endast möjliga på grund av evenemangsförökning (ofta kallad händelsebubbla). Varje gång en händelse avfyras kommer den att bubbla hela vägen upp (till dokumentroten). De delegerar hanteringen av en händelse till ett icke-förändrat förfäderelement, därav namnet "delegerade" händelser.
Så i exemplet ovan kommer att klicka på <a>
elementlänk utlösa "klicka" -händelse i dessa element i denna ordning:
- en
- li
- ul
- kropp
- html
- dokumentrot
Lösning
Att veta vad händelse bubblar gör, kan vi fånga en av de önskade händelserna som sprids upp genom vår HTML.
En bra plats att fånga det i detta exempel är <ul>
elementet, eftersom det elementet inte är dynamiskt:
$('ul').on('click', 'a', function () {
console.log(this.href); // jQuery binds the event function to the targeted DOM element
// this way `this` refers to the anchor and not to the list
// Whatever you want to do when link is clicked
});
I ovan:
- Vi har "ul" som är mottagaren av denna händelse lyssnare
- Den första parametern ('klick') definierar vilka händelser vi försöker upptäcka.
- Den andra parametern ( 'a') används för att förklara där behoven händelse härröra från (av alla underordnade element enligt denna händelse lyssnarens mottagare, ul).
- Slutligen är den tredje parametern koden som körs om krav på första och andra parametrar är uppfyllda.
I detalj hur lösningen fungerar
- Användarklickar
<a>
element - Det utlöser klickhändelse på
<a>
elementet. - Händelsen börjar bubbla upp mot dokumentroten.
- Händelsen bubblar först till
<li>
-elementet och sedan till<ul>
-elementet. - Händelse lyssnaren körs eftersom
<ul>
elementet har händelsen lyssnaren ansluten. - Händelsen lyssnar först upp den utlösande händelsen. Den bubblande händelsen är "klick" och lyssnaren har "klick", det är ett pass.
- Lyssnarkontrollerna försöker matcha den andra parametern ('a') till varje objekt i bubbelkedjan. Eftersom det sista objektet i kedjan är ett "a" stämmer det med filtret och det är också ett pass.
- Koden i den tredje parametern körs med det matchade objektet eftersom det är
this
. Om funktionen inte inkluderar ett samtal tillstopPropagation()
fortsätter händelsen att spridas uppåt mot roten (document
).
Obs! Om en lämplig förfader som inte ändras är inte tillgänglig / bekväm bör du använda document
. Använd som vana inte 'body'
av följande skäl:
-
body
har ett fel, att göra med styling, det kan betyda att mushändelser inte bubblar till det. Detta är beroende av webbläsare och kan hända när den beräknade kroppshöjden är 0 (t.ex. när alla barnelement har absoluta positioner). Mushändelser bubblar alltid för attdocument
. -
document
alltid i ditt skript, så du kan koppla delegerade hanterare tilldocument
utanför en DOM-klar hanterare och vara säker på att de fortfarande fungerar.
Dokument laddar händelse. Ladda ()
Om du vill att ditt skript ska vänta tills en viss resurs laddades, till exempel en bild eller en PDF, kan du använda .load()
, som är en genväg för genväg för .on( "load", handler)
.
html
<img src="image.jpeg" alt="image" id="image">
jQuery
$( "#image" ).load(function() {
// run script
});
Händelser för att upprepa element utan att använda ID: er
Problem
Det finns en serie upprepande element på sidan som du behöver veta vilken en händelse inträffade för att göra något med den specifika instansen.
Lösning
- Ge alla vanliga element en gemensam klass
- Tillämpa händelse lyssnare på en klass.
this
inre händelsehanterare är det matchande väljarelementet som händelsen inträffade på - Kör igenom den yttre mest upprepande behållaren för det här fallet genom att börja vid
this
- Använd
find()
den behållaren för att isolera andra element som är specifika för den instansen
html
<div class="item-wrapper" data-item_id="346">
<div class="item"><span class="person">Fred</span></div>
<div class="item-toolbar">
<button class="delete">Delete</button>
</div>
</div>
<div class="item-wrapper" data-item_id="393">
<div clss="item"><span class="person">Wilma</span></div>
<div class="item-toolbar">
<button class="delete">Delete</button>
</div>
</div>
jQuery
$(function() {
$('.delete').on('click', function() {
// "this" is element event occured on
var $btn = $(this);
// traverse to wrapper container
var $itemWrap = $btn.closest('.item-wrapper');
// look within wrapper to get person for this button instance
var person = $itemWrap.find('.person').text();
// send delete to server and remove from page on success of ajax
$.post('url/string', { id: $itemWrap.data('item_id')}).done(function(response) {
$itemWrap.remove()
}).fail(function() {
alert('Ooops, not deleted at server');
});
});
});
originalEvent
Ibland kommer det att finnas egenskaper som inte är tillgängliga i jQuery-händelse. Event.originalEvent
att få åtkomst till de underliggande egenskaperna
Få rullningsriktning
$(document).on("wheel",function(e){
console.log(e.originalEvent.deltaY)
// Returns a value between -100 and 100 depending on the direction you are scrolling
})
Slå på och stänga av specifika händelser via jQuery. (Namngivna lyssnare)
Ibland vill du stänga av alla tidigare registrerade lyssnare.
//Adding a normal click handler
$(document).on("click",function(){
console.log("Document Clicked 1")
});
//Adding another click handler
$(document).on("click",function(){
console.log("Document Clicked 2")
});
//Removing all registered handlers.
$(document).off("click")
Ett problem med den här metoden är att ALLA lyssnare som är bundna på document
av andra plugins osv också skulle tas bort.
Oftare än inte vill vi ta bort alla lyssnare som endast är kopplade till oss.
För att uppnå detta kan vi binda namngivna lyssnare som,
//Add named event listener.
$(document).on("click.mymodule",function(){
console.log("Document Clicked 1")
});
$(document).on("click.mymodule",function(){
console.log("Document Clicked 2")
});
//Remove named event listener.
$(document).off("click.mymodule");
Detta säkerställer att någon annan klicklyssnare inte av misstag ändras.