Uno dei compiti più comuni nello sviluppo web è la gestione degli eventi. Il nostro codice JavaScript di solito ascolta gli eventi inviati dagli elementi DOM.
Questo è il modo in cui otteniamo le informazioni dall'utente: cioè, lui o lei fa clic, digita, interagisce con la nostra pagina e dobbiamo sapere quando ciò accadrà. Aggiungere listener di eventi sembra banale ma potrebbe essere un processo difficile.
In questo articolo, vedremo un vero problema del caso e la sua soluzione 1.6K.
Un mio amico lavora come sviluppatore junior. Come tale, non ha molta esperienza con JavaScript vaniglia; tuttavia, ha dovuto iniziare a utilizzare framework come AngularJS ed Ember senza avere la comprensione fondamentale della relazione DOM-to-JavaScript. Durante il suo tempo come sviluppatore junior, è stato messo a capo di un piccolo progetto: un sito web di campagne di una sola pagina con quasi nessun JavaScript coinvolto. Ha affrontato un problema piccolo ma molto interessante che alla fine mi ha portato a scrivere Bubble.js.
Immagina di avere un popup. Uno stile piacevole Ecco il codice che usiamo per mostrare un messaggio: Abbiamo un'altra funzione Ad esempio, supponiamo di dover implementare una logica aggiuntiva se i problemi si presentano uno per uno. Diciamo che dobbiamo aggiungere due pulsanti al contenuto del popup - sì e No. Quindi, come sapremo che l'utente fa clic su di loro? Dobbiamo aggiungere listener di eventi a ognuno dei link. Per esempio: Il codice sopra funziona durante la prima esecuzione. E se avessimo bisogno di un nuovo pulsante o, peggio ancora, se avessimo bisogno di un diverso tipo di pulsante? Cioè, e se dovessimo continuare a usare Qui sono dove i problemi diventano visibili: Ci deve essere un modo migliore per farlo. Sì, c'è un approccio migliore. E no, la soluzione non è usare un framework. Prima di rivelare la risposta parliamo un po 'degli eventi nell'albero DOM. Gli eventi sono una parte essenziale dello sviluppo web. Aggiungono interattività alle nostre applicazioni e fungono da ponte tra la logica aziendale e l'utente. Ogni elemento DOM può inviare eventi. Tutto ciò che dobbiamo fare è iscriversi a questi eventi ed elaborare l'oggetto evento ricevuto. C'è un termine propagazione dell'evento che sta dietro evento ribollente e cattura di eventi entrambi sono due modi di gestire gli eventi in DOM. Usiamo il seguente markup e vediamo la differenza tra loro. Ci collegheremo Una volta premuto il collegamento, nella console viene visualizzato il seguente output: Quindi, in effetti entrambi gli elementi ricevono il Usando A volte potrebbe essere necessario invertire l'ordine e fare in modo che l'evento venga catturato dall'elemento esterno. Per raggiungere questo obiettivo, dobbiamo utilizzare un terzo parametro in È così che il nostro browser elabora gli eventi quando interagiamo con la pagina. Okay, allora perché abbiamo passato una parte dell'articolo parlando di bolle e cattura. Li abbiamo citati perché il bubbling è la risposta dei nostri problemi con il popup. Dovremmo impostare gli ascoltatori dell'evento non sui collegamenti ma su Seguendo questo approccio, eliminiamo i problemi elencati all'inizio. Il codice sopra è migliore di quello con cui abbiamo iniziato. Tuttavia, continua a non funzionare allo stesso modo. Come abbiamo detto, Abbiamo recuperato il valore di Tuttavia, non è una buona idea usare il Anche il nostro codice diventa un po 'migliore. Possiamo rimuovere le virgolette usate in Il risultato potrebbe essere visto in questo JSBin. Ho applicato la soluzione di cui sopra in diversi progetti, quindi aveva senso avvolgerla in una libreria. Si chiama Bubble.js ed è disponibile in GitHub. È un file 1.6K che fa esattamente ciò che abbiamo fatto sopra. Trasformiamo il nostro esempio popup da usare Invece di Una volta incluso C'è anche una sintassi alternativa: Di default, Il gestore JavaScript continua a ricevere l'oggetto Event. Quindi, in questo caso, siamo in grado di mostrare il testo del campo: A volte abbiamo bisogno di catturare non uno ma molti eventi inviati dallo stesso elemento. Trova la variante finale in un JSBin qui. La soluzione fornita in questo articolo si basa completamente sul bubbling dell'evento. In alcuni casi Per esempio: Se posizioniamo il mouse su "scegli" ed esegui un clic, l'elemento che invia l'evento non è il Certo, la comunicazione con il DOM è una parte essenziale del nostro sviluppo di applicazioni, ma è una pratica comune che usiamo i framework solo per bypassare quella comunicazione. Non ci piace aggiungere gli ascoltatori ancora e ancora. Non ci piace il debug di bug strani a doppio evento. La verità è che se sappiamo come funziona il browser, siamo in grado di eliminare questi problemi. Bubble.js è solo un risultato di poche ore di lettura e un'ora di codifica: è la nostra soluzione 1.6K a uno dei problemi più comuni.var popup = document.querySelector ('. popup'); var showMessage = function (msg) popup.style.display = 'block'; popup.innerHTML = msg; ... showMessage ('Caricamento in corso, attendere prego');
HideMessage
che cambia il display
proprietà a nessuna
e nasconde il popup. L'approccio potrebbe funzionare nel caso più generico ma ha ancora alcuni problemi. var content = 'Sei sicuro?
'; contenuto + = 'Sì'; contenuto + = 'No'; showMessage (contenuto); var addListeners = function (yesCB, noCB) popup.querySelector ('. popup - yes'). addEventListener ('click', yesCB); popup.querySelector ('. popup - no'). addEventListener ('click', noCB); showMessage (contenuto); addListeners (function () console.log ('Pulsante Sì cliccato');, function () console.log ('Nessun pulsante cliccato'););
elementi ma con nomi di classi diversi? Non possiamo usare lo stesso
addListeners
funzione, ed è fastidioso creare un nuovo metodo per ogni variazione di popup.
showMessage
chiamata. Dobbiamo pensarci sempre e sincronizzare i due processi.apparire
variabile. Dobbiamo chiamarlo querySelector
funzione al posto di document.querySelector
. Altrimenti, potremmo selezionare un elemento sbagliato.addEventListener
chiamate. Non è affatto ASCIUTTO.Comprendere la gestione degli eventi
clic
gestori di eventi per entrambi gli elementi. Tuttavia, poiché ci sono nidificati l'uno nell'altro, entrambi riceveranno il clic
evento.document.querySelector ('. wrapper'). addEventListener ('click', function (e) console.log ('. wrapper cliccato');); document.querySelector ('a'). addEventListener ('click', function (e) console.log ('a clic su'););
un clic su. wrapper cliccato
clic
evento. Innanzitutto, il link e poi il stopPropagation
metodo: document.querySelector ('a'). addEventListener ('click', function (e) e.stopPropagation (); console.log ('a clickked'););
stopPropagation
funzione, indichiamo che l'evento non deve essere inviato ai genitori.addEventListener
. Se passiamo vero
come valore lo faremo esfogo. Per esempio:document.querySelector ('. wrapper'). addEventListener ('click', function (e) console.log ('. wrapper cliccato');, true); document.querySelector ('a'). addEventListener ('click', function (e) console.log ('a clic su');, true);
La soluzione
var content = 'Sei sicuro?
'; contenuto + = 'Sì'; contenuto + = 'No'; var addListeners = function () popup.addEventListener ('click', function (e) var link = e.target;); showMessage (contenuto); addListeners ();
showMessage
è chiamato. Finché il apparire
variabile è vivo prenderemo gli eventi.addListeners
una volta, usiamo il apparire
variabile anche una volta. Non dobbiamo tenerlo o passarlo tra i metodi.showMessage
. Abbiamo accesso all'ancora cliccata in questo e.target
punta all'elemento premuto.e.target
punta al clic etichetta. Quindi, lo useremo per distinguere il sì e No pulsanti.
var addListeners = function (callbacks) popup.addEventListener ('click', function (e) var link = e.target; var buttonType = link.getAttribute ('classe'); if (callbacks [buttonType]) callbacks [ buttonType] (e);); ... addListeners ('popup - yes': function () console.log ('Yes');, 'popup - no': function () console.log ('No');) ;
classe
attributo e usarlo come chiave. Le diverse classi puntano a diversi callback. classe
attributo. È riservato per applicare gli stili visivi all'elemento e il suo valore può cambiare in qualsiasi momento. Come sviluppatori JavaScript, dovremmo usare dati
attributi.var content = 'Sei sicuro?
'; contenuto + = 'Sì'; contenuto + = 'No';addListeners
funzione:addListeners (yes: function () console.log ('Yes');, no: function () console.log ('No'););
Bubble.js
Bubble.js
. La prima cosa che dobbiamo cambiare è il markup usato:var content = 'Sei sicuro?
'; contenuto + = 'Sì'; contenuto + = 'No';Dati-action
dovremmo usare Dati-bubble-action
. bubble.min.js
nella nostra pagina, abbiamo un globale bolla
funzione disponibile. Accetta un selettore di elementi DOM e restituisce l'API della libreria. Il sopra
il metodo è quello che aggiunge gli ascoltatori:bubble ('. popup') .on ('yes', function () console.log ('Yes');) .on ('no', function () console.log ('No'); );
bubble ('. popup'). on (yes: function () console.log ('Yes');, no: function () console.log ('No'););
Bubble.js
ascolta clic
eventi, ma c'è un'opzione per cambiarlo. Aggiungiamo un campo di input e ne ascoltiamo keyup
evento:bubble ('. popup'). on (... input: function (e) console.log ('Nuovo valore:' + e.target.value););
Dati-bubble-action
accetta più valori separati da virgola:fallback
e.target
potrebbe non indicare l'elemento di cui abbiamo bisogno. tag ma il
campata
elemento.Sommario