Een van de meest voorkomende taken bij webontwikkeling is evenementenbeheer. Onze JavaScript-code luistert meestal naar gebeurtenissen die door de DOM-elementen worden verzonden.
Dit is hoe we informatie krijgen van de gebruiker: dat wil zeggen, hij of zij klikt, typt, communiceert met onze pagina en we moeten weten zodra dit gebeurt. Het toevoegen van gebeurtenislisteners ziet er triviaal uit maar kan een moeilijk proces zijn.
In dit artikel zullen we een echt probleem met de zaak en zijn 1.6K-oplossing zien.
Een vriend van mij werkt als junior-ontwikkelaar. Als zodanig heeft hij niet veel ervaring met vanilla JavaScript; hij moest echter frameworks zoals AngularJS en Ember gebruiken zonder de fundamentele kennis van de DOM-naar-JavaScript-relatie te kennen. Tijdens zijn tijd als junior-ontwikkelaar kreeg hij de leiding over een klein project: websites met één pagina en bijna geen JavaScript. Hij stond voor een klein maar zeer interessant probleem dat me uiteindelijk leidde tot het schrijven van Bubble.js.
Stel je voor dat we een popup hebben. Een mooie stijl Hier is de code die we gebruiken om een bericht te tonen: We hebben een andere functie Stel bijvoorbeeld dat we aanvullende logica moeten implementeren als de problemen één voor één worden opgelost. Laten we zeggen dat we twee knoppen moeten toevoegen aan de inhoud van de pop-up - Ja en Nee. Dus, hoe zullen we weten dat de gebruiker erop klikt? We moeten event listeners toevoegen aan elk van de links. Bijvoorbeeld: De bovenstaande code werkt tijdens de eerste run. Wat als we een nieuwe knop nodig hebben, of erger nog, wat als we een ander soort knop nodig hebben? Dat wil zeggen, wat als we zouden blijven gebruiken Hier zijn de problemen zichtbaar: Er moet een betere manier zijn om dit te doen. Ja, er is een betere aanpak. En nee, de oplossing is niet om een kader te gebruiken. Laten we, voordat we het antwoord onthullen, een beetje praten over de gebeurtenissen in de DOM-boom. Evenementen zijn een essentieel onderdeel van webontwikkeling. Ze voegen interactiviteit toe aan onze applicaties en fungeren als een brug tussen de bedrijfslogica en de gebruiker. Elk DOM-element kan gebeurtenissen verzenden. Het enige dat we moeten doen, is abonneren op deze evenementen en het ontvangen evenement-object verwerken. Er is een term evenement propagatie dat staat achter event bubbling en het vastleggen van gebeurtenissen beide zijn twee manieren om gebeurtenissen af te handelen in DOM. Laten we de volgende markup gebruiken en het verschil tussen deze markeringen zien. We zullen hechten Zodra we op de link hebben gedrukt, zien we de volgende uitvoer in de console: Dus beide elementen ontvangen inderdaad de Door het gebruiken van Soms moeten we de volgorde misschien omkeren en de gebeurtenis laten vastlopen door het buitenelement. Om dit te bereiken, moeten we een derde parameter gebruiken in Dat is hoe onze browser de gebeurtenissen verwerkt wanneer we de pagina gebruiken. Oké, dus waarom brachten we een deel van het artikel door met praten over borrelen en vastleggen. We noemden ze omdat borrelen het antwoord is op onze problemen met de pop-up. We moeten de gebeurtenislisteners niet instellen op de links, maar op de Door deze aanpak te volgen, elimineren we de problemen die in het begin worden genoemd. De bovenstaande code is beter dan de code waarmee we zijn begonnen. Werkt echter nog steeds niet op dezelfde manier. Zoals we al zeiden, We haalden de waarde van de Het is echter geen goed idee om de Onze code wordt ook een beetje beter. We kunnen de aanhalingstekens verwijderen die in Het resultaat was te zien in deze JSBin. Ik heb de oplossing hierboven in verschillende projecten toegepast, dus het was logisch om er een bibliotheek van te maken. Het heet Bubble.js en het is beschikbaar in GitHub. Het is een 1.6K-bestand dat precies doet wat we hierboven hebben gedaan. Laten we ons pop-upvoorbeeld transformeren om te gebruiken In plaats van Zodra we opnemen Er is ook een alternatieve syntaxis: Standaard, De JavaScript-handler ontvangt nog steeds het Event-object. In dit geval kunnen we de tekst van het veld weergeven: Soms moeten we niet één maar veel gebeurtenissen vangen die door hetzelfde element worden verzonden. Vind hier de laatste variant in een JSBin. De oplossing in dit artikel is volledig afhankelijk van het borrelen van het evenement. In sommige gevallen Bijvoorbeeld: Als we onze muis boven "kiezen" plaatsen en een klik uitvoeren, is het element dat de gebeurtenis verzendt niet de Toegegeven, communicatie met de DOM is een essentieel onderdeel van onze applicatie-ontwikkeling, maar het is een gebruikelijke praktijk dat we kaders gebruiken om die communicatie te omzeilen.. We houden er niet van om steeds weer luisteraars toe te voegen. We vinden het niet leuk om rare bugs met dubbele gebeurtenissen te debuggen. De waarheid is dat als we weten hoe de browser werkt, we deze problemen kunnen oplossen. Bubble.js is slechts één resultaat van een paar uur lezen en een uur coderen - het is onze 1.6K-oplossing voor een van de meest voorkomende problemen.var popup = document.querySelector ('. popup'); var showMessage = function (msg) popup.style.display = 'block'; popup.innerHTML = msg; ... showMessage ('Bezig met laden. Even geduld');
hideMessage
dat verandert de tonen
eigendom aan geen
en verbergt de pop-up. De aanpak kan in het meest generieke geval werken, maar heeft nog steeds enkele problemen. var content = 'Weet je het zeker?
'; inhoud + = 'Ja'; inhoud + = 'Nee'; showMessage (inhoud); var addListeners = function (yesCB, noCB) popup.querySelector ('. popup - yes'). addEventListener ('klik', yesCB); popup.querySelector ('. popup - no'). addEventListener ('klik', noCB); showMessage (inhoud); addListeners (function () console.log ('Yes button clicked');, function () console.log ('Geen knop aangeklikt'););
elementen maar met verschillende klassenamen? We kunnen hetzelfde niet gebruiken
addListeners
functie, en het is vervelend om een nieuwe methode te maken voor elke variant van de pop-up.
toon bericht
roeping. We moeten daar voortdurend aan denken en de twee processen synchroniseren.pop-up
variabel. We moeten het noemen querySelector
functie in plaats van document.querySelector
. Anders kunnen we een verkeerd element selecteren.addEventListener
noemt. Het is helemaal niet droog.Eventafhandeling begrijpen
Klik
event handlers voor beide elementen. Omdat er echter genest zijn in elkaar, zullen ze allebei de Klik
evenement.document.querySelector ('. wrapper'). addEventListener ('klik', functie (e) console.log ('. wrapper geklikt');); document.querySelector ('a'). addEventListener ('klik', functie (e) console.log ('een aangeklikte'););
een aangeklikte .wrapper heeft geklikt
Klik
evenement. Eerst de link en dan de stopPropagation
methode: document.querySelector ('a'). addEventListener ('klik', functie (e) e.stopPropagation (); console.log ('een geklikte'););
stopPropagation
functie, geven we aan dat de gebeurtenis niet naar de ouders moet worden verzonden.addEventListener
. Als we passeren waar
als een waarde die we zullen doen event capturing. Bijvoorbeeld:document.querySelector ('. wrapper'). addEventListener ('klik', functie (e) console.log ('. wrapper clicked');, true); document.querySelector ('a'). addEventListener ('klik', functie (e) console.log ('een aangeklikte');, true);
De oplossing
var content = 'Weet je het zeker?
'; inhoud + = 'Ja'; inhoud + = 'Nee'; var addListeners = function () popup.addEventListener ('klik', functie (e) var link = e.target;); showMessage (inhoud); addListeners ();
toon bericht
wordt genoemd. Zolang de pop-up
variabele leeft, we vangen de gebeurtenissen op.addListeners
eenmaal gebruiken we de pop-up
variabele ook één keer. We hoeven het niet te houden of door te geven tussen de methoden.toon bericht
. We hebben daar toegang tot het geklikte anker e.target
wijst naar het ingedrukte element.e.target
wijst naar de aangeklikte label. Dus, we zullen dat gebruiken om het te onderscheiden Ja en Nee toetsen.
var addListeners = function (callbacks) popup.addEventListener ('klik', functie (e) var link = e.target; var buttonType = link.getAttribute ('class'); if (callbacks [buttonType]) callbacks [ buttonType] (e);); ... addListeners ('popup - yes': function () console.log ('Yes');, 'popup - no': function () console.log ('No');) ;
klasse
attribuut en gebruik het als een sleutel. De verschillende klassen wijzen naar verschillende callbacks. klasse
attribuut. Het is gereserveerd voor het toepassen van visuele stijlen op het element en de waarde ervan kan op elk moment veranderen. Als JavaScript-ontwikkelaars zouden we moeten gebruiken gegevens
attributen.var content = 'Weet je het zeker?
'; inhoud + = 'Ja'; inhoud + = 'Nee';addListeners
functie:addListeners (yes: function () console.log ('Yes');, no: function () console.log ('No'););
Bubble.js
Bubble.js
. Het eerste dat we moeten veranderen is de gebruikte markup:var content = 'Weet je het zeker?
'; inhoud + = 'Ja'; inhoud + = 'Nee';data-actie
we zouden moeten gebruiken data-bubble-actie
. bubble.min.js
op onze pagina hebben we een wereldwijde bubbel
functie beschikbaar. Het accepteert een DOM-elementselector en retourneert de API van de bibliotheek. De op
methode is degene die de luisteraars toevoegt:bubble ('. popup') .on ('yes', function () console.log ('Yes');) .on ('nee', functie () console.log ('Nee'); );
bubble ('. popup'). on (yes: function () console.log ('Yes');, no: function () console.log ('No'););
Bubble.js
luistert naar Klik
evenementen, maar er is een optie om dat te veranderen. Laten we een invoerveld toevoegen en luisteren naar zijn keyup
evenement:bubble ('. popup'). on (... input: function (e) console.log ('Nieuwe waarde:' + e.target.value););
data-bubble-actie
accepteert meerdere waarden, gescheiden door een komma:fallbacks
e.target
mag niet verwijzen naar het element dat we nodig hebben. tag maar de
span
element.Samenvatting