javascript - Direkte vs. Delegert - jQuery .on()


Jeg prøver å forstå denne spesielle forskjellen mellom direkte og delegerte hendelseshåndterere ved bruk av jQuery .on()-metoden. Spesielt den siste setningen i dette avsnittet:

Når en selector er oppgitt, refereres hendelseshåndtereren til som delegert. Håndtereren blir ikke kalt når hendelsen oppstår direkte på det bundne elementet, men kun for underordnede (indre elementer) som matcher selektoren. jQuery bobler hendelsen fra hendelsesmålet opp til elementet hvor håndtereren er festet (dvs. fra det innerste til det ytterste elementet) og kjører håndtereren for alle elementer langs den banen som matcher selektoren.

Hva betyr det med «kjører håndtereren for alle elementer»? Jeg laget en testside for å eksperimentere med konseptet. Men begge de følgende konstruksjonene fører til samme oppførsel:

$("div#target span.green").on("click", function() {
   alert($(this).attr("class") + " is clicked");
});

eller,

$("div#target").on("click", "span.green", function() {
   alert($(this).attr("class") + " is clicked");
});

Kanskje noen kunne vise til et annet eksempel for å tydeliggjøre dette poenget? Takk.

Svar #1

Sak 1 (direkte):

$("div#target span.green").on("click", function() {...});

== Hei! Jeg vil at hver span.green inne i div#target skal høre etter: når du blir klikket på, gjør X.

Case 2 (delegerte):

$("div#target").on("click", "span.green", function() {...});

== Hei, div#target! Når noen av barnelementene dine som er "span.green" blir klikket på, gjør X med dem.

Med andre ord...

I tilfelle 1 har hver av disse elementene fått instruksjoner individuelt. Hvis nye elementer opprettes, vil de ikke ha hørt instruksjonen og vil ikke reagere på klikk. Hvert element er direkte ansvarlig for sine egne hendelser.

I tilfelle 2 har kun beholderen fått instruksjonen; den er ansvarlig for å merke klikk på vegne av sine barneelementer. Arbeidet med å fange hendelser har blitt delegerert. Dette betyr også at instruksjonen vil bli utført for barneelementer som blir opprettet i fremtiden.

Svar #2

Den første måten, $ ("div#target span.green").on(), binder en klikkhåndterer direkte til span-ene som matcher selektoren på det tidspunktet koden blir utført. Dette betyr at hvis andre span legges til senere (eller får endret klassen sin slik at de matcher), vil de ha gått glipp av en klikkhåndterer og vil ikke ha en. Det betyr også at hvis du senere fjerner "green"-klassen fra en av span-ene, vil klikkhåndtereren fortsatt kjøre - jQuery holder ikke oversikt over hvordan håndtereren ble tildelt og sjekker ikke om selektoren fortsatt matcher.

Den andre måten, $ ("div#target").on(), binder en klikkerhandler til div-en(e) som stemmer (igjen, dette er mot de som stemmer på det tidspunktet), men når et klikk skjer et sted i div-en vil handler-funksjonen kun bli kjørt hvis klikket ikke bare skjedde i div-en, men i et barneelement som matcher selector-en i den andre parameteren til .on(), "span.green". Gjort på denne måten spiller det ingen rolle når disse barn-spanene ble opprettet, å klikke på dem vil fortsatt kjøre handleren.

Så for en side som ikke dynamisk legger til eller endrer innholdet sitt, vil du ikke merke noen forskjell mellom de to metodene. Hvis du dynamisk legger til ekstra barneelementer, betyr den andre syntaksen at du ikke trenger å bekymre deg for å tilordne klikkhåndterere til dem fordi du allerede har gjort det én gang på forelderen.

Relaterte artikler