JavaScript: propagazione degli eventi + modali
Eventi in JavaScript
Se associate un event listener al "click“ su un elemento, cosa succede se l’utente clicca un figlio di quell’elemento?
Eventi in JavaScript
Esempio: se cliccate su <img>, verrà eseguita la funzione toggle? (CodePen)
Eventi in JavaScript
Sì, un evento click impostato su un elemento verrà eseguito se cliccate su un figlio di quell’elemento.
Nell’esempio, se associate un listener all’evento click sul div, e l’utente clicca sull’img dentro il div, l’handler verrà eseguito
Event.currentTarget vs target
Potete accedere all’elemento cliccato o all’elemento al quale è associato l’event listener:
Event listener multipli
Che succede se avete degli event listener associati sia ad un elemento che a un suo figlio?
(CodePen)
Event bubbling
Questo ordinamento degli eventi (dal più interno al più esterno) è chiamato bubbling.
div id="interno"
div id="esterno"
stopPropagation()
Per impedire che un evento risalga lungo la catena di genitori, possiamo utilizzare event.stopPropagation():
Event capturing
È possibile imporre che la propagazione dell’evento vada nella direzione opposta, aggiungendo un parametro a addEventListener:�
event.addEventListener(
'click', onClick, { capture: true} );
Questo ordinamento degli eventi (dal più esterno al più interno) è chiamato capturing. (CodePen)
div id=“interno"
div id=“esterno"
stopPropagation()
Possiamo usare event.stopPropagation() anche nel capturing.
Dettagli tecnici
Al verificarsi di un evento, il browser crea un "propagation path" dal target risalendo fino all’elemento html
(Con target si intende l’elemento cliccato, non quello a cui è associato l’event listener)
html
html
div id="interno"
html
body
div id="esterno"
"Capture phase"
Il browser parte dalla cima del propagation path e invoca tutti gli event listener con capture="true". Questa è la "capture phase" (w3c)
html
body
div id="esterno"
div id="interno"
"Target phase"
Quindi, il browser invoca gli event listener associati al target. Questa è la "target phase" (w3c)
div id="interno"
html
html
html
body
div id="esterno"
"Bubble phase"
Per gli eventi con bubbles=true (es. click), il browser risale lungo il propagation path e invoca gli event listener con capture="false". Questa è la "bubble phase" (w3c)
div id="interno"
html
html
html
body
div id="esterno"
preventDefault()
Quando un evento ha un comportamento predefinito dal browser (ad es., il click su un collegamento apre una nuova pagina), è possibile disabilitarlo tramite:
In pratica
Cose di cui non preoccuparvi:
Cose di cui preoccuparvi:
Esempio: album fotografico
Implementiamo una pagina che mostri un album di foto
Esempio: album fotografico
Implementiamo una pagina che mostri un album di foto
Album fotografico: HTML
Definiamo entrambe le “viste” :
Album fotografico: CSS (album)
Il CSS per la vista dell’album è abbastanza immediato
Album fotografico: CSS (modale)
La vista modale è meno immediata, ma niente di nuovo.
Album fotografico: CSS (immagine)
Se le dimensioni originali dell’immagine rientrano nello spazio a disposizione, usa quelle; altrimenti, limita l’altezza e la larghezza e quelle del contenitore.
Album fotografico: CSS (modale)
Di default, la vista modale è nascosta tramite display: none;
Lista di foto
photo-list.js definisce una lista globale chiamata PHOTO_LIST contenenti i percorsi delle immagini da caricare.
Thumbnail delle foto
Riempiamo la vista dell’album iterando PHOTO_LIST e aggiungendo elementi <img> ad #album-view.
Click sulle foto
Quando un’immagine nella vista dell’album viene cliccata:
Chiudere la modale
Quando l’utente clicca sulla vista modale:
Problemi
Posizionare la modale
window.pageYOffset rappresenta lo scostamente verticale della viewport rispetto all’inizio della pagina.
Quindi, possiamo posizionare la modale ad una distanza dall’inizio della pagina pari a quel valore!
Attribute style
Ogni HTMLElement ha un attributo style che permette di impostare direttamente le proprietà CSS dell’elemento:
element.style.top = window.pageYOffset + 'px';
In generale, non dovreste utilizzare l’attributo style; è meglio rimuovere e aggiungere classi tramite classList.
Ma se dobbiamo modificare le proprietà CSS in base a valori dinamici restituiti da JavaScript, dobbiamo per forza impostare l’attributo style direttamente.
Impedire lo scroll
La regola body { overflow: hidden; } disabilita lo scroll sulla pagina.
Chiudere la modale (2)