Aproape tot ceea ce faci în JavaScript ar trebui să înceapă atunci când se întâmplă ceva: utilizatorul face clic pe un buton, se deplasează peste un meniu, apasă o cheie, primești ideea. Este destul de simplu să faci cu biblioteci cum ar fi jQuery, dar știi cum să conduci evenimente în JavaScript primar? Astăzi, o să vă învăț exact asta!
Manipularea evenimentelor JavaScript nu este știință pentru rachete. Desigur, există diferențe în browser (ce te-ai aștepta?), Dar odată ce ai să te agiți și să-ți construiești propriile funcții de ajutor chiar și pe terenul de joc, vei fi bucuros că o știi. Chiar dacă intenționați să folosiți o bibliotecă pentru astfel de lucruri, este bine să știți ce se întâmplă sub suprafață. Începem.
Manipularea cea mai de bază a evenimentului în JavaScript este manipularea evenimentelor la nivelul 0. Este destul de ușor: trebuie doar să atribuiți funcția proprietății evenimentului pe element. Observa:
var element = document.getElementById ('myElement'); element.onclick = function () alertă ("funcția dvs. aici"); ;
Odată ce am elementul, am setat onclick
proprietate egală cu o funcție. Acum, când element
se face clic, funcția va fi rulată și vom vedea o casetă de alertă.
Dar cum am știut să o folosesc onclick
? Puteți obține o listă de evenimente disponibile la Wikipedia. Frumusețea despre metoda de nivel 0 este că este acceptată pe toate browserele utilizate astăzi. Dezavantajul este că puteți înregistra fiecare eveniment o dată cu fiecare element. Deci, aceasta va provoca o singură alertă:
element.onclick = funcția () alert ('funcția 1'); ; element.onclick = funcția () alertă ("suprascriu funcția 1");
Numai a doua funcție se va executa atunci când elementul este apăsat, deoarece am reasignat proprietatea onclick. Pentru a elimina un handler de evenimente, putem să-l setăm la nul.
element.onclick = null;
Deși oferă doar funcționalități de bază, suportul consistent din toate browserele face ca manipularea evenimentului de nivel 0 să fie o opțiune valabilă pentru proiecte foarte simple.
Acum, că încălziți evenimentele JavaScript, să discutăm două aspecte importante înainte de a trece la tehnici mai bune: obiectul evenimentului și acest
cuvinte cheie. Când un eveniment este executat, există o mulțime de informații despre evenimentul pe care ați putea dori să îl cunoașteți: ce cheie a fost apăsată? la ce element a fost făcut clic? a făcut clic cu butonul din stânga, din dreapta sau din mijloc? Toate aceste date și mai mult sunt stocate într-un obiect de eveniment. Pentru toate browserele, cu excepția Internet Explorer, puteți ajunge la acest obiect prin trecerea acestuia ca parametru al funcției de manipulare. În IE, îl puteți obține de la variabila globală window.event
. Nu este greu să rezolvi această diferență.
funcția myFunction (evt) evt = evt || window.event; / * ... * / element.onclick = funcția mea;
myFunction
ia parametrul de eveniment pentru toate browserele bune și îl redistribuim window.event
dacă EVT
nu există. Vom analiza câteva din proprietățile obiectului evenimentului un pic mai târziu.
acest
cheia este importantă în cadrul funcțiilor de gestionare a evenimentelor; se referă la elementul care a primit evenimentul.
element.onclick = funcția () this.style.backgroundColor = 'roșu'; // aceeași ca element.style.backgroundColor = 'roșu';
Din păcate, în Internet Explorer, acest
nu se referă la elementul acționat; se referă la obiectul ferestrei. Asta e inutil, dar ne vom uita la o modalitate de a remedia asta putin.
Manipularea evenimentelor la nivelul 2 este specificația W3C pentru evenimentele DOM. Este destul de simplu, de fapt.
element.addEventListener ('mouseover', myFunction, false);
Se numește metoda addEventListener
. Primul parametru este tipul de eveniment pe care dorim să îl ascultăm. De obicei, este același nume cu evenimentele de nivel 0, fără prefixul "pe". Al doilea parametru este fie un nume de funcție, fie o funcție în sine. Parametrul final determină dacă captem sau nu; o vom discuta într-o clipă.
Una dintre marile beneficii ale utilizării addEventListener
este că acum putem aloca mai multe evenimente pentru un eveniment unic pe un singur element:
element.addEventListener ('dblclick', logSuccessToConsole, false); element.addEventListener ('dblclick', funcția () console.log ('această funcție nu suprimă prima');, false);
Pentru a elimina aceste dispozitive, utilizați funcția removeEventListener
. Deci, pentru a elimina funcția pe care am adăugat-o mai sus, facem acest lucru:
element.removeEventListener ('dblclick', logSuccessToConsole, false);
Parametrul final din addEventListner
și removeEventListener
este un boolean care definește dacă declanșăm evenimentul în stadiul de captură sau de bubble. Iată ce înseamnă:
Când faceți clic pe un element, faceți clic, de asemenea, pe fiecare element al strămoșilor săi.
Salvați locul de muncă
Dacă dau clic pe # salva deschidere
, De asemenea, am făcut clic # Bara de instrumente div
, div # înveliș
, și corp
. Deci, dacă oricare dintre aceste elemente au ascultători de evenimente care ascultă pentru clicuri, se vor apela funcțiile lor respective. Dar ce ordine ar trebui să fie chemată? Asta decide ultimul parametru. În spec. W3C, evenimentul nostru de clic va începe la corp
și deplasați în jos lanțul până când ajunge la # salva deschidere
; aceasta este etapa de capturare. Apoi, merge de la # salva deschidere
înapoi la corp
; asta e stadiul de bubble. Acest lucru este ușor de reținut, deoarece bulele plutesc în sus. Nu toate evenimentele bubble; că diagrama Wikipedia vă va spune care dintre ele fac și care nu.
Deci, dacă parametrul de captură este setat la Adevărat
, evenimentul va fi declanșat pe drum; dacă este setat fals
, acesta va fi declanșat pe drum.
S-ar putea să fi observat că, până acum, toate exemplele mele au stabilit captarea la fals, astfel că evenimentul este declanșat în stadiul de bubble. Acest lucru se datorează faptului că Internet Explorer nu are o fază de captare. În IE, evenimentele doar bubble.
IE are propriul mod propriu de a lucra cu evenimente. Folosește attachEvent
.
element.attachEvent ("onclick", runThisFunction);
Din moment ce evenimentele IE sunt doar bubble, nu aveți nevoie de a treia variabilă. Primele două sunt aceleași ca și cu addEventListener
, cu mare excepție că IE necesită prefixul "pe" pentru tipul evenimentului. Desigur, puteți atribui mai multe evenimente de același tip unui element individual cu acest model. Pentru a elimina evenimentele, utilizați detachEvent
.
element.detachEvent ("onclick", runThisFunction);
Ce-ar fi dacă elementele voastre nu vor ca părinții să afle despre evenimentele lor? Nu este greu să te ascunzi. În IE, utilizați cancelBubble
proprietatea asupra obiectului evenimentului care trece la funcția apelată. Pentru restul, puteți folosi stopPropogation
, de asemenea, pe obiectul evenimentului.
e.cancelBubble = true; dacă (e.stopPropagation) e.stopPropagation ();
stopPropogation
metoda va opri, de asemenea, evenimentele din piesele lor în timpul etapei de capturare.
Aș fi dispus să pariez că majoritatea proprietăților din obiectul evenimentului vor rămâne neutilizate, dar sunt câteva dintre cele selectate pe care le-ați găsit de neprețuit. Să ne uităm la cei câțiva.
ţintă
proprietatea este cel mai adânc element pe care a fost făcut clic. În imaginea de mai sus, puteți vedea că am făcut clic Butonul h1 #
. În IE, această proprietate este numită srcElement
; pentru a ajunge la această proprietate, faceți ceva de genul:
var țintă = e.target || e.srcElement;
currentTarget
proprietatea este elementul care are evenimentul chiar acum. În acea captură de ecran, currentTarget
este div # înveliș
. Aceasta înseamnă că am făcut clic Butonul h1 #
, dar obiectul evenimentului a fost înregistrat în consola în funcția numită de div # înveliș
ascultător al evenimentului.
Dar asta vă va arunca pentru o buclă: IE nu are o proprietate curentăTarget sau ceva asemănător. Reamintind faptul că IE nici nu lasă acest
egal cu elementul care declanșează evenimentul, acest lucru înseamnă că nu avem nici o modalitate de a obține elementul care a declanșat evenimentul atunci când acesta este bubbling în sus (ceea ce înseamnă că un descendent al elementului a fost click). Confuz? Poate un exemplu va ajuta: dacă, în Internet Explorer, avem acest HTML ...
Buton
... și acest handler de evenimente ...
var par = document.getElementById ("părinte"); parent.attachEvent ("onclick", doSomething);
... atunci când faceți clic pe Durata # copil
iar evenimentul se bulează până la div # părinte
, nu avem nici o cale din interiorul funcției Fă ceva
pentru a ajunge la element (în acest caz, div # părinte
) evenimentul a fost declanșat la.
Există alte proprietăți ale obiectului evenimentului pe care le veți găsi utile, în funcție de caz. La un eveniment de tastatură (tasta, tastatura, apăsarea tastei), veți fi cod cheie
si charCode
. Veți putea afla dacă utilizatorul a ținut apăsată tasta alt, shift sau ctrl (cmd) în timp ce apăsați / dă clic pe. Explorați obiectele evenimentului de evenimente diferite și vedeți cu ce aveți de lucrat!
Am întâlnit două probleme principale în studierea evenimentelor de până acum.
currentTarget
proprietate, și acest
Obiectul trimite referințe la obiectul ferestrei.Pentru a rezolva aceste probleme, să construim două funcții cu suport pentru cross-browser, unul pentru a conecta evenimente și unul pentru a le elimina.
Vom începe cu asta addEvent
; iată primul rând:
var addEvent = funcție (element, tip, fn) if (element.attachEvent) element.attachEvent (tip "on" +, fn); altceva element.addEventListener (type, fn, false);
Am atribuit o funcție anonimă variabilei addEvent
pentru motivele pe care le veți vedea într-un minut. Tot ce trebuie să facem este să verificăm dacă elementul are attachEvent
metodă. Dacă da, suntem în IE și vom folosi acea metodă. Dacă nu, putem folosi addEventListener
.
Cu toate acestea, acest lucru nu stabilește faptul că nu avem nicio modalitate de a accesa elementul părinte al evenimentului în IE. Pentru a face acest lucru, vom face funcția un atribut al elementului; în acest fel, este percepută ca o metodă a elementului și acest
va fi egal cu elementul. Da, știu, strălucitoare, nu-i așa? Ei bine, eu nu pot lua nici un credit: această idee provine dintr-un post blog de John Resig.
var addEvent = funcție (element, tip, fn) if (element.attachEvent) element ['e' + tip + fn] = fn; elementul [type + fn] = funcția () element ['e' + type + fn] (window.event); element.attachEvent (tip "on" +, element [type + fn]); altceva element.addEventListener (type, fn, false);
Prima linie extra (element ['e' + tip + fn] = fn;
) face funcția o metodă a elementului, astfel încât acest
va egala elementul. A doua linie este o funcție care execută metoda, trecând în obiectul window.event. Acest lucru vă salvează pasul suplimentar de verificare a parametrului obiect eveniment în cadrul funcției. În cele din urmă, observați că am modificat parametrul funcției din attachEvent
metoda de a Element [tipul + fn]
.
Asta ne rezolvă cele două probleme. Acum ne putem folosi addEvent
în toate browserele cu o experiență similară posibilă. Dar există o mică optimizare pe care am vrea să o facem.
Observați că de fiecare dată addEvent
funcția se numește, verifică pentru attachEvent
metodă. Nu există niciun motiv pentru care ar trebui să verificăm acest lucru de mai multe ori, indiferent de numărul de evenimente pe care vrem să le înregistrăm. Putem folosi un truc minunat care ne va permite să re-scriem addEvent
.
var addEvent = funcția (el, type, fn) if (el.attachEvent) addEvent = funcția (el, type, fn) el ['e' + type + fn] = fn; el [type + fn] = funcția () el ['e' + tip + fn] (window.event); ; el.attachEvent (tipul "on" +, el [type + fn]); altfel addEvent = funcția (el, type, fn) el.addEventListener (type, fn, false); addEvent (el, tip, fn);
Acum, dacă addEvent
se găsește metoda, vom re-scrie addEvent
pentru a include doar componentele IE; dacă nu, vom include doar părțile bune ale browserului.
Al nostru removeEvent
funcția va fi foarte asemănătoare:
var removeEvent = funcție (element, tip, fn) if (element.detachEvent) removeEvent = funcție (element, tip, fn) element.detachEvent (tip "on" + el [type + fn]); element [tip + fn] = null; altceva removeEvent = funcție (element, tip, fn) element.removeEventListener (type, fn, false); removeEvent (element, tip, fn);
Asta e pentru funcțiile evenimentului încrucișat în browsere. Există un lucru care nu-mi place despre ei, totuși: funcțiile nu sunt metode ale elementelor; în schimb, elementul este un parametru. Știu că e doar o chestiune de stil, dar îmi place
btn.addEvent ("faceți clic", doThis);
mai bun decât
addEvent (btn, 'click', doThis);
Am putea face acest lucru prin împachetarea funcțiilor noastre în acest sens:
var E = Element.prototip; E.addEvent = funcția (tip, fn) addEvent (acest tip, fn); E.removeEvent = funcție (tip, fn) removeEvent (acest tip, fn);
Acest lucru va funcționa în toate browserele moderne, precum și IE8; IE7 și IE6 sufoca pe Element
. Depinde de publicul tău; ia-l sau pleaca!
Acum că știți totul despre evenimentele JavaScript, nu vă grăbiți și completați următorul proiect cu ascultători de evenimente. Dacă aveți multe elemente care răspund la același tip de eveniment (de exemplu, faceți clic pe), este mai înțelept să profitați de bule. Puteți adăuga un ascultător de eveniment la un element strămoș, chiar și corpul, și puteți folosi proprietatea țintă / srcElement asupra obiectului evenimentului pentru a afla care element de adâncime a fost făcut clic. Aceasta se numește Delegare de evenimente. Iată un exemplu inutil:
Iată câteva coduri HTML:
Putem folosi delegarea evenimentului pentru a face față clicurilor fiecăruia Li
:
funcția de navigare (e) var el = e.target || e.srcElement; switch (el.id) caz "home": alertă ("du-te acasă"); pauză; caz "portofoliu": alertă ("verificați produsele mele"); pauză; cazul "despre": alertă ("toate aceste detalii dezgustătoare"); pauză; caz "contact": alertă ("Te-am flatat că vrei să vorbești"); pauză; implicit: alertă ("cum ai ajuns aici?"); var nav = document.getElementById ("nav"); addEvent (nav, clic, navigare);
Folosim o instrucțiune switch / case pentru a vedea id-ul elementului cu un click mai adânc. Apoi, facem ceva în consecință.
Deci, acum poți purta evenimente JavaScript cu cele mai bune dintre ele. Distrează-te cu el și puneți întrebările în comentarii!