diff --git a/2-ui/2-events/01-introduction-browser-events/article.md b/2-ui/2-events/01-introduction-browser-events/article.md index 19394e49e..bf6b015ea 100644 --- a/2-ui/2-events/01-introduction-browser-events/article.md +++ b/2-ui/2-events/01-introduction-browser-events/article.md @@ -1,93 +1,92 @@ -# Introduction to browser events +# Introduzione agli eventi del browser -*An event* is a signal that something has happened. All DOM nodes generate such signals (but events are not limited to DOM). +*Un evento* è un segnale che sta ad indicare che è avvenuto qualcosa. Tutti i nodi DOM generano questi segnali (anche se gli eventi non sono limitati al DOM). -Here's a list of the most useful DOM events, just to take a look at: +Ecco quindi una lista, degli eventi DOM più utili: -**Mouse events:** -- `click` -- when the mouse clicks on an element (touchscreen devices generate it on a tap). -- `contextmenu` -- when the mouse right-clicks on an element. -- `mouseover` / `mouseout` -- when the mouse cursor comes over / leaves an element. -- `mousedown` / `mouseup` -- when the mouse button is pressed / released over an element. -- `mousemove` -- when the mouse is moved. +**Eventi del mouse:** +- `click` -- quando si clicca col mouse su un elemento (i dispositivi touch lo generano tramite il tocco). +- `contextmenu` -- quando si clicca col tasto destro su un elemento. +- `mouseover` / `mouseout` -- quando il cursore passa sopra/abbandona un elemento. +- `mousedown` / `mouseup` -- quando viene premuto/rilasciato il pulsante del mouse su un elemento. +- `mousemove` -- quando si sposta il mouse. -**Keyboard events:** -- `keydown` and `keyup` -- when a keyboard key is pressed and released. +**Eventi da tastiera:** +- `keydown` e `keyup` -- quando viene premuto e rilasciato un tasto. -**Form element events:** -- `submit` -- when the visitor submits a `
`. -- `focus` -- when the visitor focuses on an element, e.g. on an ``. +**Eventi degli elementi del form:** +- `submit` -- quando l'utente invia un ``. +- `focus` -- quando l'utente attiva il focus su un elemento, ad esempio su un ``. -**Document events:** -- `DOMContentLoaded` -- when the HTML is loaded and processed, DOM is fully built. +**Eventi del Document:** +- `DOMContentLoaded` -- quando l'HTML viene caricato e processato, e la costruzione del DOM è stata completata. -**CSS events:** -- `transitionend` -- when a CSS-animation finishes. +**Eventi dei CSS:** +- `transitionend` -- quando termina un'animazione CSS (CSS-animation). -There are many other events. We'll get into more details of particular events in next chapters. +Ci sono molti altri eventi più specifici, che verranno affrontati in dettaglio nei prossimi capitoli. -## Event handlers +## Gestori di evento -To react on events we can assign a *handler* -- a function that runs in case of an event. +Per reagire agli eventi possiamo assegnare un *gestore* (handler). Questo non è altro che una funzione che viene eseguita contestualmente alla generazione di un evento. -Handlers are a way to run JavaScript code in case of user actions. +I gestori, quindi, sono un modo per eseguire codice JavaScript al verificarsi delle azioni dell'utente ed esistono vari modi per assegnare un evento. -There are several ways to assign a handler. Let's see them, starting from the simplest one. +Partiamo dal più semplice. -### HTML-attribute +### Attributo HTML -A handler can be set in HTML with an attribute named `on`. +Un gestore può essere impostato in HTML con un attributo chiamato `on`. -For instance, to assign a `click` handler for an `input`, we can use `onclick`, like here: +Ad esempio, per assegnare un gestore al `click` di un `input`, possiamo usare `onclick`: ```html run - + ``` -On mouse click, the code inside `onclick` runs. +Al click del mouse, il codice dentro `onclick` verrà eseguito. -Please note that inside `onclick` we use single quotes, because the attribute itself is in double quotes. If we forget that the code is inside the attribute and use double quotes inside, like this: `onclick="alert("Click!")"`, then it won't work right. +Nota bene che dentro `onclick` useremo gli apici singoli, in quanto l'attributo stesso è già inserito all'interno di apici doppi. Se ci dimenticassimo che il codice stesse dentro l'attributo, ed usassimo gli apici doppi come in questo caso: `onclick="alert("Click!")"`, il codice non funzionerebbe. -An HTML-attribute is not a convenient place to write a lot of code, so we'd better create a JavaScript function and call it there. +Un attributo HTML non è un buon posto per scrivere tanto codice, quindi è molto meglio creare una funzione JavaScript per poterla richiamare. -Here a click runs the function `countRabbits()`: +In questo esempio, al click viene eseguita la funzione `countRabbits()`: ```html autorun height=50 - + ``` +Come sappiamo, gli attributi HTML non sono case-sensitive, quindi scrivere `ONCLICK` va bene tanto quanto `onClick` e `onCLICK`...ma solitamente vengono scritti in minuscolo: `onclick`. -As we know, HTML attribute names are not case-sensitive, so `ONCLICK` works as well as `onClick` and `onCLICK`... But usually attributes are lowercased: `onclick`. +### Proprietà del DOM -### DOM property +Possiamo assegnare un gestore usando una proprietà DOM `on`. -We can assign a handler using a DOM property `on`. - -For instance, `elem.onclick`: +Ad esempio, `elem.onclick`: ```html autorun - + ``` -If the handler is assigned using an HTML-attribute then the browser reads it, creates a new function from the attribute content and writes it to the DOM property. +Se il gestore viene assegnato usando un attributo HTML, il browser lo riconosce, crea una nuova funzione partendo dal contenuto dell'attributo e la scrive nella proprietà del DOM. -So this way is actually the same as the previous one. +In sostanza, questa modalità equivale alla precedente. -These two code pieces work the same: +I due codici messi a confronto, infatti, lavorano alla stessa maniera: 1. Only HTML: @@ -106,147 +105,146 @@ These two code pieces work the same: */!* ``` +L'unica differenza è che nel primo esempio, l'attributo HTML viene usato per inizializzare il `button.onclick`, invece nel secondo per inizializzare lo script. -In the first example, the HTML attribute is used to initialize the `button.onclick`, while in the second example -- the script, that's all the difference. - -**As there's only one `onclick` property, we can't assign more than one event handler.** +**Dal momento che c'è solo una proprietà `onclick`, non è possibile assegnare più di un gestore evento.** -In the example below adding a handler with JavaScript overwrites the existing handler: +Aggiungendo un gestore tramite JavaScript, si va a sovrascrivere il gestore esistente: ```html run height=50 autorun - + ``` -To remove a handler -- assign `elem.onclick = null`. +Per rimuovere un gestore, assegnare `elem.onclick = null`. -## Accessing the element: this +## Accedere all'elemento: this -The value of `this` inside a handler is the element. The one which has the handler on it. +Il valore di `this` all'interno di un gestore è l'elemento contenente il gestore. -In the code below `button` shows its contents using `this.innerHTML`: +Qui il `button` mostra il suo contenuto tramite `this.innerHTML`: ```html height=50 autorun - + ``` -## Possible mistakes +## Possibili errori -If you're starting to work with events -- please note some subtleties. +Se stai affrontando da poco l'argomento degli eventi, nota bene alcune sottigliezze. -We can set an existing function as a handler: +Possiamo impostare come gestore una funzione esistente: ```js function sayThanks() { - alert('Thanks!'); + alert('Grazie!'); } elem.onclick = sayThanks; ``` -But be careful: the function should be assigned as `sayThanks`, not `sayThanks()`. +Ma attenzione: la funzione deve essere assegnata scrivendo `sayThanks`, e non `sayThanks()`. ```js -// right +// corretto button.onclick = sayThanks; -// wrong +// errato button.onclick = sayThanks(); ``` -If we add parentheses, then `sayThanks()` becomes is a function call. So the last line actually takes the *result* of the function execution, that is `undefined` (as the function returns nothing), and assigns it to `onclick`. That doesn't work. +Se aggiungessimo le parentesi, allora `sayThanks()` diverrebbe una chiamata a funzione. Di conseguenza il valore dell'assegnazione dell'ultima riga dell'esempio, sarebbe il risultato della chiamata, ossia `undefined` (dato che la funzione non restituisce nulla), e verrebbe assegnato ad `onclick`. Ovviamente così non potrebbe andare bene, ed inoltre non sarebbe nemmeno l'effetto voluto. -...On the other hand, in the markup we do need the parentheses: +...D'altra parte, però, nel markup abbiamo bisogno delle parentesi: ```html ``` -The difference is easy to explain. When the browser reads the attribute, it creates a handler function with body from the attribute content. +La differenza è molto semplice: quando il browser legge l'attributo, crea una funzione che fa da gestore, il cui corpo è il contenuto dell'attributo. -So the markup generates this property: +Quindi il markup crea questa proprietà: ```js button.onclick = function() { *!* - sayThanks(); // <-- the attribute content goes here + sayThanks(); // <-- il contenuto dell'attributo va a finire qui */!* }; ``` -**Don't use `setAttribute` for handlers.** +**Non usare `setAttribute` per i gestori.** -Such a call won't work: +Ed ancora, una chiamata del genere non funzionerà: ```js run no-beautify -// a click on will generate errors, -// because attributes are always strings, function becomes a string +// un click sul genera errori, +// perché gli attributi sono sempre stringhe, e la funzione diventa una stringa document.body.setAttribute('onclick', function() { alert(1) }); ``` -**DOM-property case matters.** +**Il case della proprietà DOM è rilevante.** -Assign a handler to `elem.onclick`, not `elem.ONCLICK`, because DOM properties are case-sensitive. +Assegnare un gestore a `elem.onclick`, e non a `elem.ONCLICK`, in quanto le proprietà del DOM sono case-sensitive. ## addEventListener -The fundamental problem of the aforementioned ways to assign handlers -- we can't assign multiple handlers to one event. +Il problema principale della sopracitata maniera di assegnare i gestori è che non abbiamo modo di assegnare dei gestori multipli a un evento. -Let's say, one part of our code wants to highlight a button on click, and another one wants to show a message on the same click. +Ipotizziamo che una parte del nostro codice serva ad evidenziare un pulsante al click, e che un altro serva a mostrare un messaggio al medesimo click. -We'd like to assign two event handlers for that. But a new DOM property will overwrite the existing one: +Per fare questo sarebbe bello poter assegnare due eventi distinti, ma sappiamo che ogni nuova proprietà DOM con lo stesso nome, sovrascriverà la precedente: ```js no-beautify input.onclick = function() { alert(1); } // ... -input.onclick = function() { alert(2); } // replaces the previous handler +input.onclick = function() { alert(2); } // sostituisce il gestore precedente ``` -Developers of web standards understood that long ago and suggested an alternative way of managing handlers using special methods `addEventListener` and `removeEventListener`. They are free of such a problem. +Gli sviluppatori degli standard web hanno intuito la cosa tempo addietro, e hanno suggerito un modo alternativo per trattare i gestori, usando i metodi speciali `addEventListener` e `removeEventListener`, i quali non sono affetti da questi problemi. -The syntax to add a handler: +Ecco la sintassi per aggiungere un gestore: ```js element.addEventListener(event, handler, [options]); ``` `event` -: Event name, e.g. `"click"`. +: Nome dell'evento, ad esempio `"click"`. `handler` -: The handler function. +: La funzione che fa da gestore. `options` -: An additional optional object with properties: - - `once`: if `true`, then the listener is automatically removed after it triggers. - - `capture`: the phase where to handle the event, to be covered later in the chapter . For historical reasons, `options` can also be `false/true`, that's the same as `{capture: false/true}`. - - `passive`: if `true`, then the handler will not call `preventDefault()`, we'll explain that later in . +: Un oggetto opzionale aggiuntivo con delle proprietà: + - `once`: se `true`, il listener viene rimosso automaticamente una volta innescato. + - `capture`: la fase in cui deve essere gestito l'evento, argomento affrontato più avanti nel capitolo . Per ragioni storiche, `options` possono essere anche `false/true`, ed è equivale a scrivere `{capture: false/true}`. + - `passive`: se `true`, il gestore non chiamerà `preventDefault()`, anche questo, verrà spiegato successivamente nel capitolo . -To remove the handler, use `removeEventListener`: +Per rimuovere l'evento, si usa `removeEventListener`: ```js element.removeEventListener(event, handler, [options]); ``` -````warn header="Removal requires the same function" -To remove a handler we should pass exactly the same function as was assigned. +````warn header="La rimozione richiede la stessa identica funzione" +Per rimuovere un gestore dobbiamo passare come parametro, la stessa funzione che abbiamo usato per l'assegnazione. -This doesn't work: +Il seguente codice non fa quello che ci aspetteremmo: ```js no-beautify -elem.addEventListener( "click" , () => alert('Thanks!')); +elem.addEventListener( "click" , () => alert('Grazie!')); // .... -elem.removeEventListener( "click", () => alert('Thanks!')); +elem.removeEventListener( "click", () => alert('Grazie!')); ``` -The handler won't be removed, because `removeEventListener` gets another function -- with the same code, but that doesn't matter, as it's a different function object. +Il gestore non verrà rimosso, perchè `removeEventListener` prende come parametro un'altra funzione: è certamente con lo stesso codice, ma questo non ha alcuna rilevanza, dal momento che è un oggetto funzione differente (fanno riferimento a due differenti indirizzi di memoria). -Here's the right way: +La maniera corretta per farlo è questa: ```js function handler() { @@ -258,112 +256,111 @@ input.addEventListener("click", handler); input.removeEventListener("click", handler); ``` -Please note -- if we don't store the function in a variable, then we can't remove it. There's no way to "read back" handlers assigned by `addEventListener`. +Nota bene: se non assegnassimo la funzione a una variabile, non potremmo rimuoverla: non c'è alcun modo di "risalire" ai gestori assegnati tramite `addEventListener`. ```` -Multiple calls to `addEventListener` allow to add multiple handlers, like this: +Chiamate multiple a `addEventListener` permettono di aggiungere gestori multipli: ```html run no-beautify ``` -As we can see in the example above, we can set handlers *both* using a DOM-property and `addEventListener`. But generally we use only one of these ways. +Come visto nell'esempio, possiamo impostare i gestori *in entrambi i modi* sia con l'ausilio di una proprietà DOM che di `addEventListener`. Generalmente però, scegliamo un solo approccio. -````warn header="For some events, handlers only work with `addEventListener`" -There exist events that can't be assigned via a DOM-property. Only with `addEventListener`. +````warn header="Per alcuni eventi, i gestori funzionano solo con `addEventListener`" +Esistono eventi che non possono essere assegnati tramite una proprietà DOM, ma solo con `addEventListener`. -For instance, the `DOMContentLoaded` event, that triggers when the document is loaded and DOM is built. +Un esempio di ciò, è l'evento `DOMContentLoaded`, innescato quando viene completamente caricato il documento e costruita tutta la struttura del DOM. ```js -// will never run +// non viene mai eseguito document.onDOMContentLoaded = function() { - alert("DOM built"); + alert("DOM costruito"); }; ``` ```js -// this way it works +// in questo modo funziona document.addEventListener("DOMContentLoaded", function() { - alert("DOM built"); + alert("DOM costruito"); }); ``` -So `addEventListener` is more universal. Although, such events are an exception rather than the rule. +Conseguentemente, `addEventListener` è più universale, benché questi eventi siano un'eccezione più che la regola. ```` -## Event object +## Oggetto evento -To properly handle an event we'd want to know more about what's happened. Not just a "click" or a "keydown", but what were the pointer coordinates? Which key was pressed? And so on. +Per gestire correttamente un evento, vorremmo saperne di più su cosa è avvenuto. Non solamente se è stato un "click" o un "keydown", ma, ad esempio, quali erano le coordinate del puntatore? Che tasto è stato premuto? E così via. -When an event happens, the browser creates an *event object*, puts details into it and passes it as an argument to the handler. +Quando c'è un evento, il browser crea un *oggetto evento* (event object), inserisce i dettagli al suo interno e lo passa come argomento al gestore. -Here's an example of getting pointer coordinates from the event object: +Ecco un esempio per ottenere le coordinate dall'oggetto evento: ```html run - + ``` -Some properties of `event` object: +Alcune proprietà dell'oggetto `event`: `event.type` -: Event type, here it's `"click"`. +: Tipo di evento, in questo caso è un `"click"`. `event.currentTarget` -: Element that handled the event. That's exactly the same as `this`, unless the handler is an arrow function, or its `this` is bound to something else, then we can get the element from `event.currentTarget`. +: L'elemento che ha gestito l'evento. Questo è equivalente a `this`, ma se il gestore è una arrow function, o se il suo `this` è legato a qualcos'altro, possiamo usare `event.currentTarget`. `event.clientX / event.clientY` -: Window-relative coordinates of the cursor, for pointer events. +: Coordinate del cursore relative alla Window, per eventi del puntatore. -There are more properties. Many of them depend on the event type: keyboard events have one set of properties, pointer events - another one, we'll study them later when we come to different events in details. +Esistono tante altre proprietà., molte delle quali dipendono dal tipo di evento: gli eventi della tastiera hanno un gruppo di proprietà, gli eventi del puntatore un altro ancora, e li studieremo più avanti quando andremo a vedere i vari eventi nel dettaglio. -````smart header="The event object is also available in HTML handlers" -If we assign a handler in HTML, we can also use the `event` object, like this: +````smart header="L'oggetto evento è disponibile anche nei gestori HTML" +Anche se assegniamo un gestore dentro l'HTML, possiamo usare l'oggetto `evento`: ```html autorun height=60 ``` -That's possible because when the browser reads the attribute, it creates a handler like this: `function(event) { alert(event.type) }`. That is: its first argument is called `"event"`, and the body is taken from the attribute. +Questo è possibile perché quando il browser legge l'attributo, crea un gestore con questa forma: `function(event) { alert(event.type) }`. Il primo argomento viene chiamato `"event"`, e il corpo è preso dall'attributo. ```` -## Object handlers: handleEvent - -We can assign not just a function, but an object as an event handler using `addEventListener`. When an event occurs, its `handleEvent` method is called. +## Gestori oggetto: handleEvent -For instance: +Con `addEventListener` possiamo assegnare non solo una funzione, ma anche un oggetto. Quando viene generato un evento, viene chiamato il suo metodo `handleEvent`. +Ad esempio: ```html run - + ``` -As we can see, when `addEventListener` receives an object as the handler, it calls `obj.handleEvent(event)` in case of an event. - -We could also use a class for that: +Come possiamo osservare, se `addEventListener` riceve un oggetto come gestore, allora chiama `obj.handleEvent(event)` nel caso ci sia un evento. +Possiamo usare anche una classe: ```html run - + ``` -Here the same object handles both events. Please note that we need to explicitly setup the events to listen using `addEventListener`. The `menu` object only gets `mousedown` and `mouseup` here, not any other types of events. +L'oggetto gestisce entrambi gli eventi. Nota bene che usando `addEventListener` dobbiamo impostare esplicitamente gli eventi affinché rimangano in ascolto. + -The method `handleEvent` does not have to do all the job by itself. It can call other event-specific methods instead, like this: +Nel nostro esempio, l'oggetto `menu` rimane in ascolto solamente per `mousedown` e `mouseup`, e nessun altro tipo di evento. +Tuttavia, il metodo `handleEvent` non deve necessariamente fare tutto il lavoro da solo. Può infatti chiamare altri metodi specifici per tipologia di evento: ```html run - + ``` -Now event handlers are clearly separated, that may be easier to support. +Qui i gestori sono chiaramente separati, il che può essere più comodo da gestire. -## Summary +## Riepilogo -There are 3 ways to assign event handlers: +Ci sono 3 modalità per assegnare dei gestori di evento: -1. HTML attribute: `onclick="..."`. -2. DOM property: `elem.onclick = function`. -3. Methods: `elem.addEventListener(event, handler[, phase])` to add, `removeEventListener` to remove. +1. Attributo HTML: `onclick="..."`. +2. Proprietà DOM: `elem.onclick = function`. +3. Metodi: `elem.addEventListener(event, handler[, phase])` per aggiungerlo, `removeEventListener` per rimuoverlo. -HTML attributes are used sparingly, because JavaScript in the middle of an HTML tag looks a little bit odd and alien. Also can't write lots of code in there. +Gli attributi HTML vengono usati raramente, perchè un JavaScript nel bel mezzo di un tag HTML, non solo è un po' strano, ma è anche avulso dal contesto. Inoltre in questo modo non vi si può inserire dentro tanto codice. -DOM properties are ok to use, but we can't assign more than one handler of the particular event. In many cases that limitation is not pressing. +Le proprietà DOM si possono usare, ma non potremo assegnare più di un gestore per un particolare evento. In molti casi questa limitazione non è troppo pesante. -The last way is the most flexible, but it is also the longest to write. There are few events that only work with it, for instance `transitionend` and `DOMContentLoaded` (to be covered). Also `addEventListener` supports objects as event handlers. In that case the method `handleEvent` is called in case of the event. +L'ultimo modo è il più flessibile, ma è anche il più lungo da scrivere. Alcuni eventi funzionano solo con quest'ultima modalità, ad esempio `transitionend` e `DOMContentLoaded` (affrontato più avanti). Inoltre `addEventListener` supporta gli oggetti come gestori di evento. In questo caso, però, verrà chiamato il metodo `handleEvent` al verificarsi degli eventi. -No matter how you assign the handler -- it gets an event object as the first argument. That object contains the details about what's happened. +Non importa come assegni un gestore, in ogni caso il primo argomento passato sarà un oggetto evento, contenente i dettagli su ciò che è avvenuto. -We'll learn more about events in general and about different types of events in the next chapters. +Nei prossimi capitoli, avremo modo di approfondire il tema degli eventi in generale e le loro differenti tipologie.