Verschil tussen jQuery `klik`, `bind`, `live`, `delegate`, `trigger` en `on` functies (met een voorbeeld)?

Ik heb de documentatie van elke functie op de jQuery official websitegelezen, maar er is geen vergelijkingslijst tussen onderstaande functies:

$().click(fn)
$().bind('click',fn)
$().live('click',fn)
$().delegate(selector, 'click', fn)
$().trigger('click') // UPDATED
$().on('click', selector ,fn); // more UPDATED

Vermijd alle referentielinks.

Hoe werken alle bovenstaande functies precies en welke hebben in welke situatie de voorkeur?

Opmerking:Als er andere functie(s) zijn met dezelfde functionaliteit of hetzelfde mechanisme, geef dan een toelichting.

Bijwerken

Ik heb ook een functie $.triggergezien. Werkt het vergelijkbaar met de bovenstaande functies?

Meer update

Nu is .ontoegevoegd in v1.7 en ik denk dat deze op de een of andere manier alle bovenstaande functievereisten samen dekt.


Antwoord 1, autoriteit 100%

Voordat je dit leest, trek deze lijst met evenementen op een andere pagina, de API zelf is enorm nuttig, en alles wat ik hieronder bespreek, is rechtstreeks vanaf deze pagina gelinkt.

Ten eerste is .click(function)letterlijk een snelkoppeling voor .bind('click', function)zijn ze equivalent . Gebruik ze bij het binden van een handler direct aan een element, zoals dit:

$(document).click(function() {
  alert("You clicked somewhere in the page, it bubbled to document");
});

Als dit element wordt vervangen of weggegooid, is deze handler er niet meer. Ook elementen die er niet waren toen deze code werd uitgevoerdom de handler toe te voegen (bijv. de selector vond het toen) zullen de handler niet krijgen.

.live()en .delegate()zijn op dezelfde manier gerelateerd, .delegate()gebruikt feitelijk .live()intern, ze luisteren allebei naar gebeurtenissen die opborrelen. Dit werkt voor nieuwe en oude elementen, ze bubbelen evenementen op dezelfde manier. U gebruikt deze wanneer uw elementen kunnen veranderen, b.v. het toevoegen van nieuwe rijen, lijstitems, enz. Als u geen bovenliggende/gemeenschappelijke voorouder heeft die op de pagina blijft en op geen enkel moment wordt vervangen, gebruikt u .live(), zoals dit:

$(".clickAlert").live('click', function() {
  alert("A click happened");
});

Als je echter ergens een bovenliggend element hebt dat niet wordt vervangen (dus de gebeurtenishandlers gaan niet tot ziens), moet je dit afhandelen met .delegate(), als volgt:

$("#commonParent").delegate('.clickAlert', 'click', function() {
  alert("A click happened, it was captured at #commonParent and this alert ran");
});

Dit werkt bijna hetzelfde als .live(), maar het evenement bubbelt minder keer voordat het wordt vastgelegd en de handlers worden geëxecuteerd. Een ander veelgebruikt gebruik van beide is dat je klasse verandert op een element en niet langer overeenkomt met de selector die je oorspronkelijk gebruikte… met deze methoden wordt de selector geëvalueerd op het moment van de gebeurtenis, als het komt overeen, de handler wordt uitgevoerd … dus het element dat niet langer overeenkomt met de selector is van belang, het wordt niet meer uitgevoerd. Met .click()is de gebeurtenishandler echter direct gebonden aan het DOM-element, het feit dat het niet overeenkomt met de selector die werd gebruikt om het te vinden, is niet relevant … de gebeurtenis is gebonden en blijft bestaan ​​totdat dat element verdwenen is, of de handler wordt verwijderd via .unbind().

Nog een veelvoorkomend gebruik voor .live()en .delegate()is prestaties. Als je te maken hebt met veelelementen, is het duur en tijdrovend om een ​​klikhandler rechtstreeks aan elk element te koppelen. In deze gevallen is het voordeliger om een ​​enkelehandler in te stellen en bubbels het werk te laten doen, neem een blik op deze vraag waar het een enorm verschil maakte, het is een goed voorbeeld van de toepassing.


Triggeren– voor de bijgewerkte vraag

Er zijn 2 belangrijke triggerfuncties voor event-handlers beschikbaar, ze vallen onder dezelfde categorie “Event Handler Attachment” in de API, dit zijn .trigger()en .triggerHandler(). .trigger('eventName')heeft enkele ingebouwde sneltoetsen voor de veelvoorkomende gebeurtenissen, bijvoorbeeld:

$().click(fn); //binds an event handler to the click event
$().click();   //fires all click event handlers for this element, in order bound

Je kunt hier een lijst met deze snelkoppelingen bekijken.

Wat het verschil betreft, .trigger()activeert de gebeurtenishandler (maar meestal niet de standaardactie, bijv. de cursor op de juiste plek plaatsen in een aangeklikte <textarea>). Het zorgt ervoor dat de event-handlers plaatsvinden in de volgorde waarin ze waren gebonden (zoals de native event zou doen), activeert de native event-acties en blaast de DOM op.

.triggerHandler()is meestal voor een ander doel, hier probeer je alleen de gebonden handler (s) te vuren, het veroorzaakt niet dat de native gebeurtenis wordt geactiveerd, bijv. het indienen van een formulier. Het laat de DOM niet opborrelen, en het is niet ketenbaar (het retourneert wat de laatste gebeurtenishandler voor die gebeurtenis ook retourneert). Als u bijvoorbeeld een focus-gebeurtenis wilt activeren maar het object niet daadwerkelijk wilt focussen, wilt u alleen code die u bindt met .focus(fn)uit te voeren, dit zou dat doen, terwijl .trigger()zou dat doen, maar ook het element focussen en opborrelen.

Hier is een voorbeeld uit de praktijk:

$("form").submit(); //actually calling `.trigger('submit');`

Hierdoor worden alle indieningshandlers uitgevoerd, bijvoorbeeld de jQuery-validatieplug-in, probeer dan de <form>in te dienen. Als u echter alleenwilt valideren, aangezien het is aangesloten via een submitgebeurtenishandler, maar het <form>daarna niet verzendt, zou .triggerHandler('submit')kunnen gebruiken, zoals dit:

$("form").triggerHandler('submit');

De plug-in voorkomt dat de handler het formulier verzendt door eruit te bombarderen als de validatiecontrole niet slaagt, maar bij deze methode maakt het ons niet uit wat het doet. Of het nu is afgebroken of niet, we proberen niethet formulier in te dienen, we wilden het gewoon activeren om opnieuw te valideren en verder niets te doen. (Disclaimer:dit is een overbodig voorbeeld aangezien er een .validate()methode in de plug-in zit, maar het is een goede illustratie van de bedoeling)


Antwoord 2, autoriteit 17%

De eerste twee zijn equivalent.

// The following two statements do the same thing:
$("blah").click( function() { alert( "Click!" ); } );
$("blah").bind( "click", function() { alert( "Click!" ); } ); 

De tweede kan echter worden gebruikt om aan meer dan één gebeurtenis tegelijk te binden, door verschillende door spaties gescheiden gebeurtenisnamen op te geven:

$("blah").bind( "click mouseover mouseout", function() { alert( "Click! Or maybe mouse moved." ); } ); 

De .livemethode is interessanter. Beschouw het volgende voorbeeld:

<a class="myLink">A link!</a>
<a id="another">Another link!</a>
<script>
    $("a.myLink").click( function() { alert( 'Click!' ); } );
    $("a#another").addClass( "myLink" );
</script>

Nadat de tweede regel van het script is uitgevoerd, heeft de tweede link ook de CSS-klasse “myLink”. Maar het zal de gebeurtenishandler niet hebben, omdat het de klasse niet had toen het evenement werd toegevoegd.

Bedenk nu dat je wilde dat het andersom was: elke keer dat een link met klasse “myLink” ergens op de pagina verschijnt, wil je dat deze automatisch dezelfde gebeurtenis-handler heeft. Dit is heel gebruikelijk wanneer je een soort lijsten of tabellen hebt, waar je rijen of cellen dynamisch toevoegt, maar wilt dat ze zich allemaal op dezelfde manier gedragen. In plaats van elke keer opnieuw event handlers toe te wijzen, kun je de .livemethode gebruiken:

<a class="myLink">A link!</a>
<a id="another">Another link!</a>
<script>
    $("a.myLink").live( "click", function() { alert( 'Click!' ); } );
    $("a#another").addClass( "myLink" );
</script>

In dit voorbeeld krijgt de tweede link ook de gebeurtenishandler zodra deze de klasse “myLink” krijgt. Magie! 🙂

Natuurlijk is het niet zo letterlijk. Wat .liveecht doet, is de handler niet aan het gespecificeerde element zelf koppelen, maar aan de wortel van de HTML-boom (het “body”-element). Evenementen in DHTML hebben de grappige eigenschap van “opborrelen”. Overweeg dit:

<div> <a> <b>text</b> </a> </div>

Als u op “tekst” klikt, wordt eerst de <b> element krijgt een “klik” -gebeurtenis. Daarna wordt de <a> element krijgt een “klik” -gebeurtenis. En daarna de <div> element krijgt een “klik” -gebeurtenis. En zo verder – helemaal tot aan de <body> element. En dat is waar jQuery de gebeurtenis zal opvangen en kijken of er “live” handlers zijn die van toepassing zijn op het element dat de gebeurtenis in de eerste plaats heeft veroorzaakt. Netjes!

En tot slot, de .delegatemethode. Het neemt gewoon alle kinderen van je element die voldoen aan de gegeven selector en koppelt er een “live” handler aan. Kijk eens:

$("table").delegate( "td", "click", function() { alert( "Click!" ); } );
// Is equivalent to:
$("table").each( function() {
    $(this).find( "td" ).live( "click", function() { alert( "Click!" ); } );
} );

Vragen?


Antwoord 3, autoriteit 5%

Vanaf jQuery 1.7 was de .live()-methode verouderd. Als u een jQuery-versie gebruikt < 1.7 dan wordt het officieel aanbevolen om .delegate() boven .live() te gebruiken.

.live() is nu vervangen door .on().

Het is het beste om rechtstreeks naar de jQuery-site te gaan voor meer informatie, maar hier zijn de huidige versies van de .on()-methode:

.on( events [, selector] [, data], handler(eventObject) )
.on( events-map [, selector] [, data] )

http://api.jquery.com/on/


Antwoord 4

$().click(fn)en $().bind('click', fn)zijn op het eerste gezicht identiek, maar de $.bind-versie is krachtiger om twee redenen:

  1. $().bind()stelt u in staat om één handler toe te wijzen aan meerdere gebeurtenissen, bijvoorbeeld $().bind('click keyup', fn).
  2. $().bind()ondersteunt gebeurtenissen met naamruimte – een krachtige functie als u alleen bepaalde gebeurtenishandlers wilt verwijderen (unbinden) waaraan een element is gebonden – lees meer in Namespaced Events.

Live vs gedelegeerde: dit is al beantwoord in de andere antwoorden.


Antwoord 5

Hier kan het lezen van de API helpen. Ik weet het echter uit mijn hoofd, dus je kunt lui blijven (yay!).

$('#something').click(fn);
$('#something').bind('click',fn);

Er is hier geen verschil (voor zover ik weet). .clickis gewoon een handige/hulpmethode om .bind('click'

// even after this is called, all <a>s in
// <div class="dynamic_els"> will continue
// to be assigned these event handlers
$('div.dynamic_els a').live(‘click’,fn);

Dit is heel anders, omdat .livegebeurtenissen toevoegt aan de selector die je doorgeeft (die je hier niet hebt) en blijft kijken naar de DOM terwijl knooppunten worden ingevoegd / verwijderd

$('#some_element').delegate('td','click',fn);

Dit is alleen anders vanwege de manier waarop u gebeurtenishandlers toewijst. .delegateis gericht op het bubbelen van DOM-gebeurtenissen. Het basisprincipe is dat elke gebeurtenis omhoog bubbelt door de DOM-boom totdat het het root-element bereikt (documentof windowof <html>of <body>, ik weet het niet meer precies).

Hoe dan ook, je bindt een onclick-handler aan alle <td>s binnen $('#some_element')(u moet een selector specificeren, hoewel u $(document)zou kunnen zeggen). Wanneer op een van zijn kinderen wordt geklikt, borrelt de gebeurtenis naar de <td>. U kunt dan het bronelement van de gebeurtenis extraheren (wat jQuery automatisch voor u doet).

Dit is handig als er heel veel elementen zijn en je maar een paar (of één centrale) punt(en) hebt waar deze gebeurtenissen doorheen gaan. Dit bespaart de browser inspanning en geheugen om deze gebeurtenis-handlers te consolideren in minder objecten.

Other episodes