Skip to content

Commit 8aeeedb

Browse files
authored
Merge pull request #203 from pierangelomiceli/evtdeleg
Event delegation
2 parents 5c1225c + bdcf7d6 commit 8aeeedb

File tree

1 file changed

+76
-76
lines changed

1 file changed

+76
-76
lines changed
Lines changed: 76 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11

22
# Event delegation
33

4-
Capturing and bubbling allow us to implement one of most powerful event handling patterns called *event delegation*.
4+
Capturing e bubbling ci permettono di implementare uno dei pattern più potenti nella gestione degli eventi, e cioè *event delegation*.
55

6-
The idea is that if we have a lot of elements handled in a similar way, then instead of assigning a handler to each of them -- we put a single handler on their common ancestor.
6+
Il concetto di base è che se abbiamo una serie di elementi gestiti in maniera simile, allora, invece di assegnare un gestore per ognuno di essi, possiamo metterne uno solo sui loro antenati comuni.
77

8-
In the handler we get `event.target` to see where the event actually happened and handle it.
8+
Nel gestore avremo a disposizione `event.target` per controllare l'elemento dal quale è partito l'evento e poterlo quindi gestire di conseguenza.
99

10-
Let's see an example -- the [Ba-Gua diagram](http://en.wikipedia.org/wiki/Ba_gua) reflecting the ancient Chinese philosophy.
10+
Guardiamo un esempio -- il [diagramma Ba-Gua](http://en.wikipedia.org/wiki/Ba_gua) che riflette l'antica filosofia Cinese.
1111

12-
Here it is:
12+
Eccola qui:
1313

1414
[iframe height=350 src="bagua" edit link]
1515

16-
The HTML is like this:
16+
Questo è l'HTML:
1717

1818
```html
1919
<table>
@@ -30,45 +30,45 @@ The HTML is like this:
3030
</table>
3131
```
3232

33-
The table has 9 cells, but there could be 99 or 9999, doesn't matter.
33+
La tabella è composta da 9 celle, ma potrebbero anche essercene 99 o 9999, è irrilevante.
3434

35-
**Our task is to highlight a cell `<td>` on click.**
35+
**Il nostro compito è quello di evidenziare un cella `<td>` al click.**
3636

37-
Instead of assign an `onclick` handler to each `<td>` (can be many) -- we'll setup the "catch-all" handler on `<table>` element.
37+
Invece di assegnare un gestore all'`onclick` per ogni `<td>` (potrebbero essercene tantissime) -- andiamo a impostare un gestore che sarà in grado di "catturali tutti" sull'elemento `<table>`.
3838

39-
It will use `event.target` to get the clicked element and highlight it.
39+
Verrà utilizzato `event.target` per ottenere l'elemento cliccato ed evidenziarlo.
4040

41-
The code:
41+
Ecco il codice:
4242

4343
```js
4444
let selectedTd;
4545

4646
*!*
4747
table.onclick = function(event) {
48-
let target = event.target; // where was the click?
48+
let target = event.target; // dove e' stato il click?
4949

50-
if (target.tagName != 'TD') return; // not on TD? Then we're not interested
50+
if (target.tagName != 'TD') return; // non era un TD? Allora non siamo interessati
5151

52-
highlight(target); // highlight it
52+
highlight(target); // evidenzialo
5353
};
5454
*/!*
5555

5656
function highlight(td) {
57-
if (selectedTd) { // remove the existing highlight if any
57+
if (selectedTd) { // rimuove l'evidenziazione esistente, se presente
5858
selectedTd.classList.remove('highlight');
5959
}
6060
selectedTd = td;
61-
selectedTd.classList.add('highlight'); // highlight the new td
61+
selectedTd.classList.add('highlight'); // evidenzia il nuovo td
6262
}
6363
```
6464

65-
Such a code doesn't care how many cells there are in the table. We can add/remove `<td>` dynamically at any time and the highlighting will still work.
65+
Con un codice del genere non importa quante celle ci sono nella tabella. Possiamo aggiungere e rimuovere `<td>` dinamicamente in qualunque momento e l'evidenziazione continuerà a funzionare.
6666

67-
Still, there's a drawback.
67+
Ma abbiamo ancora un inconveniente.
6868

69-
The click may occur not on the `<td>`, but inside it.
69+
Il click potrebbe avvenire non sul `<td>`, ma in un elemento interno.
7070

71-
In our case if we take a look inside the HTML, we can see nested tags inside `<td>`, like `<strong>`:
71+
Nel nostro cosa se osserviamo dentro l'HTML, possiamo vedere dei tags annidati dentro il `<td>`, come ad esempio `<strong>`:
7272

7373
```html
7474
<td>
@@ -79,13 +79,13 @@ In our case if we take a look inside the HTML, we can see nested tags inside `<t
7979
</td>
8080
```
8181

82-
Naturally, if a click happens on that `<strong>` then it becomes the value of `event.target`.
82+
Naturalmente, se cliccassimo su questo `<strong>` proprio questo sarebbe il valore assunto da `event.target`.
8383

8484
![](bagua-bubble.svg)
8585

86-
In the handler `table.onclick` we should take such `event.target` and find out whether the click was inside `<td>` or not.
86+
Nel gestore `table.onclick`, dovremmo perndere questo `event.target` e scoprire se il click sia avvenuto dentro il `<td>` oppure no.
8787

88-
Here's the improved code:
88+
Ecco il codice migliorato:
8989

9090
```js
9191
table.onclick = function(event) {
@@ -99,27 +99,27 @@ table.onclick = function(event) {
9999
};
100100
```
101101

102-
Explanations:
103-
1. The method `elem.closest(selector)` returns the nearest ancestor that matches the selector. In our case we look for `<td>` on the way up from the source element.
104-
2. If `event.target` is not inside any `<td>`, then the call returns immediately, as there's nothing to do.
105-
3. In case of nested tables, `event.target` may be a `<td>`, but lying outside of the current table. So we check if that's actually *our table's* `<td>`.
106-
4. And, if it's so, then highlight it.
102+
Chiarimenti:
103+
1. Il metodo `elem.closest(selector)` ritorna l'antenato più vicino che combacia con il selettore. Nel nostro caso cerchiamo un `<td>` verso l'alto dall'elemento di origine dell'evento.
104+
2. Se `event.target` non è dentro nessun `<td>`, la chiamata esce immediatamente, dal momento che non c'è nulla da fare.
105+
3. Ne caso di tabelle annidate, `event.target` potrebbe riferirsi ad `<td>`, ma fuori dalla tabelle corrente. Quindi andiamo a controllare se `<td>` appartiene alla *nostra tabella*.
106+
4. E se così, la evidenziamo.
107107

108-
As the result, we have a fast, efficient highlighting code, that doesn't care about the total number of `<td>` in the table.
108+
Come risultato, averemo un codice di evidenziazione veloce ed efficiente, indipendente dal numero di `<td>` nella tabella.
109109

110-
## Delegation example: actions in markup
110+
## Esempio di delegation: azioni nel markup
111111

112-
There are other uses for event delegation.
112+
Esistono altri utilizzi per l'event delegation.
113113

114-
Let's say, we want to make a menu with buttons "Save", "Load", "Search" and so on. And there's an object with methods `save`, `load`, `search`... How to match them?
114+
Poniamo il caso che volessimo fare un menù con i pulsanti "Save", "Load", "Search" e cosi via, e che vi sia un oggetto con i metodi `save`, `load`, `search`... Come potremmo distinguerli?
115115

116-
The first idea may be to assign a separate handler to each button. But there's a more elegant solution. We can add a handler for the whole menu and `data-action` attributes for buttons that has the method to call:
116+
La prima idea potrebbe essere quella di assegnare dei gestori separati per ogni pulsante. Esiste però una soluzione più elegante. Possiamo aggiungere un gestore per l'intero menù e degli attributi `data-action` per i pulsanti che devono chiamare il metodo:
117117

118118
```html
119-
<button *!*data-action="save"*/!*>Click to Save</button>
119+
<button *!*data-action="save"*/!*>Clicca per salvare</button>
120120
```
121121

122-
The handler reads the attribute and executes the method. Take a look at the working example:
122+
Il gestore legge l'attributo ed esegue il metodo. Diamo uno sguardo all'esempio:
123123

124124
```html autorun height=60 run untrusted
125125
<div id="menu">
@@ -161,65 +161,65 @@ The handler reads the attribute and executes the method. Take a look at the work
161161
</script>
162162
```
163163

164-
Please note that `this.onClick` is bound to `this` in `(*)`. That's important, because otherwise `this` inside it would reference the DOM element (`elem`), not the `Menu` object, and `this[action]` would not be what we need.
164+
Nota bene che `this.onClick` è collegato a `this` nel punto `(*)`. Questo è importante, altrimenti `this` si riferirebbe all'elemento del DOM (`elem`), e non l'oggetto `Menu`, di conseguenza `this[action]` non farebbe quello di cui abbiamo bisogno.
165165

166-
So, what advantages does delegation give us here?
166+
Quindi, quali vantaggi apporta delegation qui?
167167

168168
```compare
169-
+ We don't need to write the code to assign a handler to each button. Just make a method and put it in the markup.
170-
+ The HTML structure is flexible, we can add/remove buttons at any time.
169+
+ Non abbiamo bisogno di scrivere del codice per assegnare un gestore ad ogni pulsante. Ma solo di un metodo e porlo dentro il markup.
170+
+ La struttura HTML è flessibile, possiamo aggiungere e rimuovere pulsanti in ogni momento.
171171
```
172172

173-
We could also use classes `.action-save`, `.action-load`, but an attribute `data-action` is better semantically. And we can use it in CSS rules too.
173+
Possiamo anche usare classi come `.action-save`, `.action-load`, ma un attributo `data-action` è semanticamente migliore. Inoltre possiamo usarlo nelle regole CSS.
174174

175-
## The "behavior" pattern
175+
## Il pattern "comportamentale"
176176

177-
We can also use event delegation to add "behaviors" to elements *declaratively*, with special attributes and classes.
177+
Possiamo anche usare la event delegation per aggiungere "comportamenti" agli elementi in modo *dichiarativo*, con speciali attributi e classi.
178178

179-
The pattern has two parts:
180-
1. We add a custom attribute to an element that describes its behavior.
181-
2. A document-wide handler tracks events, and if an event happens on an attributed element -- performs the action.
179+
Il pattern consta di due parti:
180+
1. Aggiungiamo un attributo personalizzato a un elemento, che descrive il suo comportamento.
181+
2. Un gestore su tutto il documento tiene traccia degli eventi, e se viene attivato un evento su un elemento con quell'attributo -- esegue l'azione.
182182

183-
### Behavior: Counter
183+
### Comportamento: contatore
184184

185-
For instance, here the attribute `data-counter` adds a behavior: "increase value on click" to buttons:
185+
Per esempio, qui l'attributo `data-counter` aggiunge un comportamento: "incrementa il valore al click" sui pulsanti:
186186

187187
```html run autorun height=60
188188
Counter: <input type="button" value="1" data-counter>
189-
One more counter: <input type="button" value="2" data-counter>
189+
Contatore di addizione: <input type="button" value="2" data-counter>
190190

191191
<script>
192192
document.addEventListener('click', function(event) {
193193
194-
if (event.target.dataset.counter != undefined) { // if the attribute exists...
194+
if (event.target.dataset.counter != undefined) { // se esiste l'attributo...
195195
event.target.value++;
196196
}
197197
198198
});
199199
</script>
200200
```
201201

202-
If we click a button -- its value is increased. Not buttons, but the general approach is important here.
202+
Se clicchiamo un pulsante -- il suo valore aumenterà. Non sono importanti i pulsanti qui, ma l'approccio in generale.
203203

204-
There can be as many attributes with `data-counter` as we want. We can add new ones to HTML at any moment. Using the event delegation we "extended" HTML, added an attribute that describes a new behavior.
204+
Possono esserci quanti attributi `data-counter` vogliamo. Possiamo aggiungerne di nuovi all'HTML in ogni momento. Usando la event delegation abbiamo "esteso" HTML, aggiunto un attributo che descrive un nuovo comportamento.
205205

206-
```warn header="For document-level handlers -- always `addEventListener`"
207-
When we assign an event handler to the `document` object, we should always use `addEventListener`, not `document.on<event>`, because the latter will cause conflicts: new handlers overwrite old ones.
206+
```warn header="Per gestori a livello di documento -- usare sempre `addEventListener`"
207+
Quando assegniamo un gestore di eventi all'oggetto `document`, dovremmo sempre usare `addEventListener`, e non `document.on<event>`, perché il secondo causerebbe conflitti: i nuovi gestori sovrascriverebbero i precedenti.
208208

209-
For real projects it's normal that there are many handlers on `document` set by different parts of the code.
209+
Per progetti reali è normale che vi siano molti gestori su `document` impostati in punti differenti del codice.
210210
```
211211
212-
### Behavior: Toggler
212+
### Comportamento: toggler
213213
214-
One more example of behavior. A click on an element with the attribute `data-toggle-id` will show/hide the element with the given `id`:
214+
Ancora un esempio di comportamento. Un click su un elemento con l'attributo `data-toggle-id` mostrerà o nasconderà l'elemento con il dato `id`:
215215
216216
```html autorun run height=60
217217
<button *!*data-toggle-id="subscribe-mail"*/!*>
218-
Show the subscription form
218+
Mostra il form di sottoscrizione
219219
</button>
220220
221221
<form id="subscribe-mail" hidden>
222-
Your mail: <input type="email">
222+
La tua mail: <input type="email">
223223
</form>
224224
225225
<script>
@@ -236,37 +236,37 @@ One more example of behavior. A click on an element with the attribute `data-tog
236236
</script>
237237
```
238238

239-
Let's note once again what we did. Now, to add toggling functionality to an element -- there's no need to know JavaScript, just use the attribute `data-toggle-id`.
239+
Notiamo ancora una volta cosa abbiamo fatto. Adesso, per aggiungere la funzionalità di toggling su un elemento -- non è necessario conoscere JavaScript, è sufficiente usare l'attributo `data-toggle-id`.
240240

241-
That may become really convenient -- no need to write JavaScript for every such element. Just use the behavior. The document-level handler makes it work for any element of the page.
241+
Questo può essere davvero conveniente -- nessuna necessità di scrivere codice JavaScript per ogni nuovo elemento di questo genere. Ci basta solo applicare il comportamento. Il gestore a livello di documento fa in modo che funzioni per ogni elemento nella pagina.
242242

243-
We can combine multiple behaviors on a single element as well.
243+
Possiamo pure combinare comportamenti multipli su un singolo elemento.
244244

245-
The "behavior" pattern can be an alternative to mini-fragments of JavaScript.
245+
Il pattern "comportamentale" può essere una alternativa a mini frammenti di JavaScript.
246246

247-
## Summary
247+
## Riepilogo
248248

249-
Event delegation is really cool! It's one of the most helpful patterns for DOM events.
249+
Event delegation è davvero fico! Uno dei pattern più utili per gli eventi del DOM.
250250

251-
It's often used to add the same handling for many similar elements, but not only for that.
251+
Spesso è usato per aggiungere dei gestori per molti elementi simili, ma non solo per quello.
252252

253-
The algorithm:
253+
L'algoritmo:
254254

255-
1. Put a single handler on the container.
256-
2. In the handler -- check the source element `event.target`.
257-
3. If the event happened inside an element that interests us, then handle the event.
255+
1. Inserire un gestore singolo a un contenitore.
256+
2. Nel gestore -- controlla l'elemento che ha originato l'evento con `event.target`.
257+
3. Se l'evento è avvenuto dentro un elemento che ci interessa, allora gestire l'evento.
258258

259-
Benefits:
259+
Benefici:
260260

261261
```compare
262-
+ Simplifies initialization and saves memory: no need to add many handlers.
263-
+ Less code: when adding or removing elements, no need to add/remove handlers.
264-
+ DOM modifications: we can mass add/remove elements with `innerHTML` and the like.
262+
+ Semplifica l'inizializzazione e salva memoria: nessuna necessità di aggiungere molti gestori.
263+
+ Meno codice: aggiungendo o rimuovendo elemento non c'è necessità di aggiungere e rimuovere gestori.
264+
+ Modifiche al DOM: possiamo aggiungere e rimuovere elementi in massa con `innerHTML` e simili.
265265
```
266266

267-
The delegation has its limitations of course:
267+
Delegation ha i suoi limiti ovviamente:
268268

269269
```compare
270-
- First, the event must be bubbling. Some events do not bubble. Also, low-level handlers should not use `event.stopPropagation()`.
271-
- Second, the delegation may add CPU load, because the container-level handler reacts on events in any place of the container, no matter whether they interest us or not. But usually the load is negligible, so we don't take it into account.
270+
- Per prima cosa, l'evento deve essere di tipo bubbling. Alcuni eventi non lo sono. Inoltre, i gestori di basso livello non dovrebbero usare `event.stopPropagation()`.
271+
- Secondo, delegation può aggiungere carico alla CPU, perché il gestore a livello di container reagisce agli eventi di qualunque posizione del container, non importa se sono degni di nota o meno. Solitamente il carico è irrisorio, e quindi non lo prendiamo in minima considerazione.
272272
```

0 commit comments

Comments
 (0)