JavaScript
HTML element kan ta emot olika events (händelser) som click, submit, mouseover, scroll m. fl.
Event bubbling är ett DOM-koncept och alla sådana HTML element följer per default konceptet event bubbling.
# EVENT BUBBLING
Prova att klicka rosa fyrkanten, sen gröna, sen gula. Vad händer i konsolen?
Event Bubbling är alltså ett koncept hur DOM:en hanterar events per default.
När ett HTML element tar emot ett event, så "bubblar" det eventet uppåt i
DOM-trädet, ända tills det når root-elementet. Processen kallas event propagation, d.v.s händelsen "fortplantar" sig. Men just i detta fall bubblar händelsen uppåt.
Men innan eventet bubblar uppåt så sker en s.k event capturing. Något man inte märker av, men finns där.
Eventet "click" bubblar till nästa element
motsatsen till event bubbling
Eventet "click" bubblar till nästa föräldra element
eventet "fortplantar" sig från där det skedde till root-elementet
motsatsen till event bubbling
Event bubbling är default för händelser i DOM.
Men det kan avbrytas med att använda stopPropagation()
Men man ska vara generellt försiktig att ändra default-beteenden, vilket lätt kan leda till buggar.
<!-- Overlay -->
<div id="overlay">
<!-- Modal content -->
<div id="modal">...</div>
</div>
# EVENT BUBBLING
const overlay = document.getElementById('overlay');
const modal = document.getElementById('modal');
overlay.addEventListener('click', function () {
console.log('Close the modal');
});
modal.addEventListener('click', function (e) {
e.stopPropagation();
});
Här används alltså stopPropagation() för att eventet i modalen inte ska bubbla vidare till overlayen. Men finns det annan lösning?
<!-- Overlay -->
<div id="overlay">
<!-- Modal content -->
<div id="modal">...</div>
</div>
# EVENT BUBBLING
const overlay = document.getElementById('overlay');
const modal = document.getElementById('modal');
overlay.addEventListener('click', function (event) {
if (event.currentTarget === event.target) {
console.log('Close the modal');
}
});
Baseras på konceptet Event bubbling.
Event delegation handlar om att hantera eventet på en högre nivå i DOM-trädet än där händelsen mottogs. D.v.s ett parent-element kan ta hand om händelsen som egentligen skedde på ett child-element
Idén är att man "delegerar" hanteringen av eventet till ett annan element.
<section>
<button>Button 1</button>
<button>Button 2</button>
<button>Button 3</button>
</section>
# EVENT DELEGATION
const buttons = document.querySelectorAll('button')
buttons.forEach(button => {
button.addEventListener("click", (event) => {
console.log(event.target.innerHTML)
})
})
Det funkar att göra så här, men skulle det kunna optimeras med event delegation?
<section>
<button>Button 1</button>
<button>Button 2</button>
<button>Button 3</button>
</section>
# EVENT DELEGATION
const parent = document.querySelector('section')
parent.addEventListener("click", (event) => {
if(event.target.tagName === 'BUTTON') {
console.log(event.target.innerHTML)
}
})
Samma logik fast endast en lyssnare - bättre prestanda. Samt kan vi lägga till nya knappar utan problem!
Text
Text
Defaultbeteendet för för ett HTML elements event-egenskaper genomförs inte.
Ex om preventDefault() sätts på en länk kommer inte webbläsaren följa länkarna.
Det är vanligt att använda vid <input type="submit"> som vanligtvis laddar om en sida. Om preventDefult() sätts på submit-eventet kommer sidan inte ladda om vid submit.