Questa traduzione è incompleta. Collabora alla traduzione di questo articolo dall’originale in lingua inglese.

Il metodo EventTarget addEventListener() imposta una funzione che verrà chiamata ogni volta che l'evento specificato viene consegnato all'elemento di destinazione. I bersagli comuni sono Element, Document, e Window, ma la destinazione può essere qualsiasi oggetto che supporti eventi (come XMLHttpRequest).

addEventListener() funziona aggiungendo una funzione o un oggetto che implementa EventListener all'elenco di listener di eventi per il tipo di evento specificato sul EventTarget sul quale è chiamato.

Sintassi

target.addEventListener(type, listener[, options]);
target.addEventListener(type, listener[, useCapture]);
target.addEventListener(type, listener[, useCapture, wantsUntrusted  ]); // Gecko/Mozilla only

Parametri

type
Una stringa sensibile al maiuscolo/minuscolo che rappresenta il tipo di evento da assegnare.
listener
L'oggetto che riceve una notifica (un oggetto che implementa l'interfaccia Event) quando si verifica un evento del tipo specificato. Questo deve essere un oggetto che implementa l'interfaccia EventListener, o una funzione. Vedi The event listener callback per i dettagli sul callback stesso.
options Optional
Un oggetto opzioni che specifica le caratteristiche del listener di eventi. Le opzioni disponibili sono:
  • capture: Un Boolean che indica che eventi di questo tipo verranno inviati al listener registrato prima di essere inviati a qualsiasi EventTarget sotto di esso nell'albero del DOM.
  • once: Un Boolean che indica che il listener dovrebbe essere invocato al massimo una volta dopo essere stato aggiunto. Se ritorna true, il listener verrebbe automaticamente rimosso quando invocato.
  • passive: Un Boolean che, se true, indica che la funzione specificata da listener non chiamerà mai preventDefault(). Se un listener passivo chiama preventDefault(), l'user agent non farà altro che generare un avviso nella console. Vedi Improving scrolling performance with passive listeners per saperne di più.
  • mozSystemGroup: Un Boolean che indica che l'ascoltatore deve essere aggiunto al gruppo di sistema. Disponibile solo nel codice in esecuzione in XBL o nel chrome del browser Firefox.
useCapture Optional
Un Boolean che indica se eventi di questo tipo verranno inviati al listener registrato prima di essere inviati a qualsiasi EventTarget sotto di esso nell'albero del DOM. Gli eventi che stanno ribollendo verso l'alto attraverso l'albero non innescheranno un ascoltatore designato ad usare il capturing. Il bubbling e la cattura degli eventi sono due modi di propagare gli eventi che si verificano in un elemento che è annidato in un altro elemento, quando entrambi gli elementi hanno registrato un handle per quell'evento. La modalità di propagazione dell'evento determina l'ordine in cui gli elementi ricevono l'evento. Vedi DOM Level 3 EventsJavaScript Event order per una spiegazione dettagliata. Se non specificato, useCapture di default è false.
Note: Per gli ascoltatori di eventi collegati al target dell'evento, l'evento si trova nella fase target, piuttosto che nelle fasi di cattura e bubbling. Gli eventi nella fase di destinazione attiveranno tutti gli ascoltatori di un elemento nell'ordine in cui sono stati registrati, indipendentemente dal parametro useCapture.
Note: useCapture non è sempre stato opzionale. Idealmente, dovresti includerlo per la massima compatibilità con i browser.
wantsUntrusted
Un parametro specifico per Firefox (Gecko). Se è true, il listener riceve eventi sintetici inviati dal contenuto web (il valore predefinito è  false per il browser chrometrue per le normali pagine Web). Questo parametro è utile per il codice trovato nei componenti aggiuntivi e anche per il browser stesso.

Valore di ritorno

undefined

Note di utilizzo

Il callback del listener di eventi

Il listener di eventi può essere specificato come funzione di callback o come oggetto che implementa EventListener, il cui metodo handleEvent() funge da funzione di callback.

La stessa funzione di callback ha gli stessi parametri e il valore di ritorno del metodo  handleEvent() cioè, il callback accetta un singolo parametro: un oggetto basato su Event che descrive l'evento che si è verificato e non restituisce nulla.

Ad esempio, un callback del gestore di eventi che può essere utilizzato per gestire entrambi gli eventi fullscreenchange e fullscreenerror potrebbe avere il seguente aspetto:

function eventHandler(event) {
  if (event.type == 'fullscreenchange') {
    /* gestire un interruttore a schermo intero */
  } else /* fullscreenerror */ {
    /* gestire un errore di commutazione a schermo intero */
  }
}

Rilevamento sicuro del supporto opzionale

Nelle versioni precedenti della specifica DOM, il terzo parametro di addEventListener() era un valore booleano che indicava se utilizzare o meno l'acquisizione. Nel corso del tempo, è diventato chiaro che erano necessarie più opzioni. Piuttosto che aggiungere altri parametri alla funzione (complicando enormemente le cose quando si tratta di valori opzionali), il terzo parametro è stato modificato in un oggetto che può contenere varie proprietà che definiscono i valori delle opzioni per configurare il processo di rimozione del listener di eventi.

Poiché i browser più vecchi (così come alcuni browser non troppo vecchi) presuppongono ancora che il terzo parametro sia un booleano, è necessario creare il codice per gestire questo scenario in modo intelligente. Puoi farlo utilizzando il rilevamento delle funzioni per ciascuna delle opzioni che ti interessano.

Ad esempio, se si desidera verificare l'opzione passive:

var passiveSupported = false;

try {
  var options = {
    get passive() { // Questa funzione verrà chiamata quando il browser
                    //     tenta di accedere alla proprietà passiva.
      passiveSupported = true;
    }
  };

  window.addEventListener("test", options, options);
  window.removeEventListener("test", options, options);
} catch(err) {
  passiveSupported = false;
}

Questo crea un oggetto options con una funzione getter per la proprietà passive; il getter imposta una flag, passiveSupported, è true se viene chiamato. Ciò significa che se il browser controlla il valore della proprietà passive sull'oggetto options, passiveSupported sarà impostato su true; altrimenti rimarrà false. Chiamiamo quindi addEventListener() tper impostare un gestore di eventi falsi, specificando tali opzioni, in modo che le opzioni vengano controllate se il browser riconosce un oggetto come terzo parametro. Quindi, chiamiamo removeEventListener() per pulire dopo noi stessi. (Nota che that handleEvent() viene ignorato sui listener di eventi che non vengono chiamati.)

Puoi verificare se un'opzione è supportata in questo modo. Basta aggiungere un getter per quella opzione usando il codice simile a quello mostrato sopra.

Quindi, quando vuoi creare un listener di eventi effettivo che utilizza le opzioni in questione, puoi fare qualcosa di simile a questo:

someElement.addEventListener("mouseup", handleMouseUp, passiveSupported
                               ? { passive: true } : false);

Qui stiamo aggiungendo un listener per l'evento mouseup sull'elemento someElement. Per il terzo parametro, se passiveSupported è true, stiamo specificando un oggetto options con passive impostato su true; altrimenti, sappiamo che dobbiamo passare un booleano e passiamo false come valore del parametro useCapture.

Se preferisci, puoi usare una libreria di terze parti come ModernizrDetect It per fare questo test per te.

È possibile ottenere ulteriori informazioni dall'articolo su EventListenerOptions dal gruppo di Web Incubator Community.

Esempi

Aggiungere un semplice listener

Questo esempio dimostra come utilizzare addEventListener() per controllare i click del mouse su un elemento.

HTML

<table id="outside">
    <tr><td id="t1">one</td></tr>
    <tr><td id="t2">two</td></tr>
</table>

JavaScript

// Funzione per modificare il contenuto di t2
function modifyText() {
  var t2 = document.getElementById("t2");
  if (t2.firstChild.nodeValue == "three") {
    t2.firstChild.nodeValue = "two";
  } else {
    t2.firstChild.nodeValue = "three";
  }
}

// Aggiungere listener di eventi alla tabella
var el = document.getElementById("outside");
el.addEventListener("click", modifyText, false);

In questo codice, modifyText() è un listener per gli eventi click registrati usando addEventListener(). Un clic in qualsiasi punto della tabella esegue il gestore ed esegue modifyText().

Risultato

Listener di eventi con funzione anonima

Qui, daremo un'occhiata a come utilizzare una funzione anonima per passare parametri nel listener di eventi.

HTML

<table id="outside">
    <tr><td id="t1">one</td></tr>
    <tr><td id="t2">two</td></tr>
</table>

JavaScript

// Funzione per modificare il contenuto di t2
function modifyText(new_text) {
  var t2 = document.getElementById("t2");
  t2.firstChild.nodeValue = new_text;    
}
 
// Funzione per aggiungere listener alla tabella
var el = document.getElementById("outside");
el.addEventListener("click", function(){modifyText("four")}, false);

Si noti che il listener è una funzione anonima che incapsula codice che è quindi, a sua volta, in grado di inviare parametri alla funzione modifyText(), che è responsabile per rispondere effettivamente all'evento.

Risultato

Listener di eventi con una funzione a freccia

Questo esempio dimostra un semplice listener di eventi implementato utilizzando la notazione della funzione a freccia.

HTML

<table id="outside">
    <tr><td id="t1">one</td></tr>
    <tr><td id="t2">two</td></tr>
</table>

JavaScript

// Funzione per modificare il contenuto di t2
function modifyText(new_text) {
  var t2 = document.getElementById("t2");
  t2.firstChild.nodeValue = new_text;    
}
 
// Aggiungere un listener alla tabella con una funzione a freccia
var el = document.getElementById("outside");
el.addEventListener("click", () => { modifyText("four"); }, false);

Risultato

Please note that while anonymous and arrow functions are similar, they have different this bindings. While anonymous (and all traditional JavaScript functions) create their own this bindings, arrow functions inherit the this binding of the containing function.

Ciò significa che le variabili e le costanti disponibili per la funzione di contenimento sono disponibili anche per il gestore di eventi quando si utilizza una funzione di freccia.

Esempio di utilizzo delle opzioni

HTML

<div class="outer">
    outer, once & none-once
    <div class="middle" target="_blank">
        middle, capture & none-capture
        <a class="inner1" href="https://www.mozilla.org" target="_blank">
            inner1, passive & preventDefault(which is not allowed)
        </a>
        <a class="inner2" href="https://developer.mozilla.org/" target="_blank">
            inner2, none-passive & preventDefault(not open new page)
        </a>
    </div>
</div>

CSS

    .outer, .middle, .inner1, .inner2 {
        display:block;
        width:520px;
        padding:15px;
        margin:15px;
        text-decoration:none;
    }
    .outer{
        border:1px solid red;
        color:red;
    }
    .middle{
        border:1px solid green;
        color:green;
        width:460px;
    }
    .inner1, .inner2{
        border:1px solid purple;
        color:purple;
        width:400px;
    }

JavaScript

    let outer  = document.getElementsByClassName('outer') [0];
    let middle = document.getElementsByClassName('middle')[0];
    let inner1 = document.getElementsByClassName('inner1')[0];
    let inner2 = document.getElementsByClassName('inner2')[0];

    let capture = {
        capture : true
    };
    let noneCapture = {
        capture : false
    };
    let once = {
        once : true
    };
    let noneOnce = {
        once : false
    };
    let passive = {
        passive : true
    };
    let nonePassive = {
        passive : false
    };
    
    
    outer.addEventListener('click', onceHandler, once);
    outer.addEventListener('click', noneOnceHandler, noneOnce);
    middle.addEventListener('click', captureHandler, capture);
    middle.addEventListener('click', noneCaptureHandler, noneCapture);
    inner1.addEventListener('click', passiveHandler, passive);
    inner2.addEventListener('click', nonePassiveHandler, nonePassive);

    function onceHandler(event) {
        alert('outer, once');
    }
    function noneOnceHandler(event) {
        alert('outer, none-once, default');
    }
    function captureHandler(event) {
        //event.stopImmediatePropagation();
        alert('middle, capture');
    }
    function noneCaptureHandler(event) {
        alert('middle, none-capture, default');
    }
    function passiveHandler(event) {
        // Unable to preventDefault inside passive event listener invocation.
        event.preventDefault();
        alert('inner1, passive, open new page');
    }
    function nonePassiveHandler(event) {
        event.preventDefault();
        //event.stopPropagation();
        alert('inner2, none-passive, default, not open new page');
    }

Risultato

Fai click rispettivamente sui contenitori esterni, centrali e interni per vedere come funzionano le opzioni.

Prima di utilizzare un particolare valore nell'oggetto options è una buona idea assicurarsi che il browser dell'utente lo supporti, poiché si tratta di un'aggiunta che non tutti i browser hanno supportato storicamente. Vedi Safely detecting option support per i dettagli.

Altre note

Why use addEventListener?

addEventListener() è il modo per registrare un listener di eventi come specificato nel DOM W3C. I benefici sono i seguenti:

  • Permette di aggiungere più di un singolo gestore per un evento. Ciò è particolarmente utile per le librerie AJAX i moduli JavaScript o qualsiasi altro tipo di codice che deve funzionare bene con altre librerie / estensioni.
  • Ti dà il controllo più fine della fase quando l'ascoltatore è attivato (capturing vs. bubbling).
  • Funziona su qualsiasi elemento del DOM, non solo sugli elementi HTML.

Il modo alternativo, più vecchio per registrare i listener, è descritto di seguito.

Aggiunta di un listener durante la spedizione dell'evento

Se un EventListener viene aggiunto ad un EventTarget mentre sta elaborando un evento, quell'evento non attiva il listener. Tuttavia, lo stesso listener può essere attivato durante una fase successiva del flusso di eventi, come la fase di bubbling.

Più listeners identici

Se più EventListeners indentici sono registrati sullo stesso EventTarget con gli stessi parametri, le istanze duplicate vengono scartate. Non causano l'EventListener da chiamare due volte e non devono essere rimossi manualmente con il metodo removeEventListener(). Nota tuttavia che quando si utilizza una funzione anonima come gestore, tali listener NON saranno identici poiché le funzioni anonime non sono identiche anche se definite utilizzando il codice sorgente invariato SAME chiamato semplicemente ripetutamente, anche se in un ciclo. Tuttavia, definire ripetutamente la stessa funzione denominata in questi casi può essere più problematico. (vedi Memory issues di seguito.)

Il valore di this all'interno del gestore

È spesso preferibile fare riferimento all'elemento su cui è stato attivato il gestore eventi, ad esempio quando si utilizza un gestore generico per un insieme di elementi simili.

Se si collega un handler ad un elemento utilizzando addEventListener(), il valore di this all'interno del gestore è un riferimento all'elemento. È uguale al valore della proprietà currentTarget dell'argomento evento che viene passato al gestore.

my_element.addEventListener('click', function (e) {
  console.log(this.className)           // registra il className di my_element
  console.log(e.currentTarget === this) // ritorna `true`
})

Come promemoria, arrow functions do not have their own this context.

my_element.addEventListener('click', (e) => {
  console.log(this.className)           // WARNING: `this` is not `my_element`
  console.log(e.currentTarget === this) // logs `false`
})

Se un gestore di eventi (ad esempio, onclick) è specificato su un elemento nel codice sorgente HTML, il codice JavaScript nel valore dell'attributo viene effettivamente racchiuso in una funzione di gestore che associa il valore di this in modo coerente con addEventListener(); un'occorrenza di this all'interno del codice rappresenta un riferimento all'elemento.

<table id="my_table" onclick="console.log(this.id);"><!-- `this` refers to the table; logs 'my_table' -->
  ...
</table>

Si noti che il valore di this all'interno di una funzione, chiamato dal codice nel valore dell'attributo, si comporta come per regole standard. Questo è mostrato nel seguente esempio:

<script>
  function logID() { console.log(this.id); }
</script>
<table id="my_table" onclick="logID();"><!-- when called, `this` will refer to the global object -->
  ...
</table>

Il valore di this all'interno di logID() è un riferimento all'oggetto globale Window (o undefined nel caso della strict mode).

Specificare this usando bind()

Il metodo Function.prototype.bind() consente di specificare il valore che dovrebbe essere usato come this per tutte le chiamate a una determinata funzione. Ciò ti consente di bypassare facilmente i problemi in cui non è chiaro quale sarà this a seconda del contesto in cui è stata chiamata la tua funzione. Nota, tuttavia, che è necessario mantenere un riferimento per l'ascoltatore in modo da poterlo rimuovere in seguito.

Questo è un esempio con e senza bind():

var Something = function(element) {
  // |this| is a newly created object
  this.name = 'Something Good';
  this.onclick1 = function(event) {
    console.log(this.name); // undefined, as |this| is the element
  };
  this.onclick2 = function(event) {
    console.log(this.name); // 'Something Good', as |this| is bound to newly created object
  };
  element.addEventListener('click', this.onclick1, false);
  element.addEventListener('click', this.onclick2.bind(this), false); // Trick
}
var s = new Something(document.body);

Un'altra soluzione sta utilizzando una funzione speciale chiamata handleEvent() per catturare qualsiasi evento:

var Something = function(element) {
  // |this| is a newly created object
  this.name = 'Something Good';
  this.handleEvent = function(event) {
    console.log(this.name); // 'Something Good', as this is bound to newly created object
    switch(event.type) {
      case 'click':
        // some code here...
        break;
      case 'dblclick':
        // some code here...
        break;
    }
  };

  // Note that the listeners in this case are |this|, not this.handleEvent
  element.addEventListener('click', this, false);
  element.addEventListener('dblclick', this, false);

  // You can properly remove the listeners
  element.removeEventListener('click', this, false);
  element.removeEventListener('dblclick', this, false);
}
var s = new Something(document.body);

Un altro modo di gestire il riferimento a this è passare ad EventListener una funzione che chiama il metodo dell'oggetto che contiene i campi a cui è necessario accedere:

class SomeClass {

  constructor() {
    this.name = 'Something Good';
  }

  register() {
    var that = this;
    window.addEventListener('keydown', function(e) {return that.someMethod(e);});
  }

  someMethod(e) {
    console.log(this.name);
    switch(e.keyCode) {
      case 5:
        // some code here...
        break;
      case 6:
        // some code here...
        break;
    }
  }

}

var myObject = new SomeClass();
myObject.register();

Legacy Internet Explorer e attachEvent

Nelle versioni di Internet Explorer precedenti a IE 9, devi usare attachEvent(), piuttosto che lo standard addEventListener(). Per IE, modifichiamo l'esempio precedente per:

if (el.addEventListener) {
  el.addEventListener('click', modifyText, false); 
} else if (el.attachEvent)  {
  el.attachEvent('onclick', modifyText);
}

C'è un inconveniente di attachEvent(): il valore di this sarà un riferimento all'oggetto window, invece dell'elemento su cui è stato chiamato.

Il metodo attachEvent() potrebbe essere associato all'evento onresize per rilevare quando alcuni elementi di una pagina Web sono stati ridimensionati. L'evento proprietario mselementresize quando abbinato al metodo addEventListener di registrazione dei gestori di eventi, fornisce funzionalità simili a onresize, attivando quando alcuni elementi HTML vengono ridimensionati.

Compatibilità

Puoi lavorare attorno a addEventListener(), removeEventListener(), Event.preventDefault(), e Event.stopPropagation() non supportati da Internet Explorer 8 di usando il seguente codice all'inizio del tuo script. Il codice supporta l'uso di  handleEvent() e anche l'evento DOMContentLoaded.

Note: useCapture non è supportato, in quanto IE 8 non ha alcun metodo alternativo. Il seguente codice aggiunge solo il supporto per IE 8. Questo polyfill di IE 8 funziona solo in modalità standard: è richiesta una dichiarazione doctype.

(function() {
  if (!Event.prototype.preventDefault) {
    Event.prototype.preventDefault=function() {
      this.returnValue=false;
    };
  }
  if (!Event.prototype.stopPropagation) {
    Event.prototype.stopPropagation=function() {
      this.cancelBubble=true;
    };
  }
  if (!Element.prototype.addEventListener) {
    var eventListeners=[];
    
    var addEventListener=function(type,listener /*, useCapture (will be ignored) */) {
      var self=this;
      var wrapper=function(e) {
        e.target=e.srcElement;
        e.currentTarget=self;
        if (typeof listener.handleEvent != 'undefined') {
          listener.handleEvent(e);
        } else {
          listener.call(self,e);
        }
      };
      if (type=="DOMContentLoaded") {
        var wrapper2=function(e) {
          if (document.readyState=="complete") {
            wrapper(e);
          }
        };
        document.attachEvent("onreadystatechange",wrapper2);
        eventListeners.push({object:this,type:type,listener:listener,wrapper:wrapper2});
        
        if (document.readyState=="complete") {
          var e=new Event();
          e.srcElement=window;
          wrapper2(e);
        }
      } else {
        this.attachEvent("on"+type,wrapper);
        eventListeners.push({object:this,type:type,listener:listener,wrapper:wrapper});
      }
    };
    var removeEventListener=function(type,listener /*, useCapture (will be ignored) */) {
      var counter=0;
      while (counter<eventListeners.length) {
        var eventListener=eventListeners[counter];
        if (eventListener.object==this && eventListener.type==type && eventListener.listener==listener) {
          if (type=="DOMContentLoaded") {
            this.detachEvent("onreadystatechange",eventListener.wrapper);
          } else {
            this.detachEvent("on"+type,eventListener.wrapper);
          }
          eventListeners.splice(counter, 1);
          break;
        }
        ++counter;
      }
    };
    Element.prototype.addEventListener=addEventListener;
    Element.prototype.removeEventListener=removeEventListener;
    if (HTMLDocument) {
      HTMLDocument.prototype.addEventListener=addEventListener;
      HTMLDocument.prototype.removeEventListener=removeEventListener;
    }
    if (Window) {
      Window.prototype.addEventListener=addEventListener;
      Window.prototype.removeEventListener=removeEventListener;
    }
  }
})();

Il modo più antico per registrare i listeners

addEventListener() è stato introdotto con la specifica DOM 2 Prima di allora, gli ascoltatori di eventi sono stati registrati come segue:

// Passando un riferimento alla funzione - non aggiungere "()" dopo di esso, che chiamerebbe la funzione!
el.onclick = modifyText;

// Using a function expression
element.onclick = function() {
  // ... function logic ...
};

Questo metodo sostituisce il listener dell'evento click esistente sull'elemento se ce n'è uno. Altri eventi e gestori di eventi associati come blur (onblur) e keypress (onkeypress) si comportano in modo simile.

Poiché era essenzialmente parte di DOM 0, questa tecnica per aggiungere listener di eventi è ampiamente supportata e non richiede uno speciale codice cross-browser. Viene normalmente utilizzato per registrare dinamicamente i listener di eventi a meno che non siano necessarie le funzionalità extra di addEventListener().

Problemi di memoria

var els = document.getElementsByTagName('*');


// Case 1
for(var i = 0; i < els.length; i++) {
  els[i].addEventListener("click", function(e){/* do something */}, false);
}


// Case 2
function processEvent(e) {
  /* do something */
}

for(var i = 0; i < els.length; i++){
  els[i].addEventListener("click", processEvent, false);
}

Nel primo caso sopra, viene creata una nuova funzione (anonima) di gestione con ogni iterazione del ciclo. Nel secondo caso, la stessa funzione dichiarata in precedenza viene utilizzata come gestore di eventi, il che si traduce in un minore consumo di memoria poiché è stata creata una sola funzione di gestore. Inoltre, nel primo caso, non è possibile chiamare removeEventListener() perché non viene mantenuto alcun riferimento alla funzione anonima (o qui, non mantenuto a nessuna delle più funzioni anonime che il loop potrebbe creare.) Nel secondo caso, è possibile eseguire myElement.removeEventListener("click", processEvent, false) perchè processEvent è il riferimento alla funzione.

In realtà, per quanto riguarda il consumo di memoria, la mancanza di mantenere un riferimento alla funzione non è il vero problema; piuttosto è la mancanza di mantenere un riferimento di funzione STATICO. In entrambi i casi di problemi di seguito, viene mantenuto un riferimento alla funzione, ma poiché viene ridefinito a ogni iterazione, non è statico. Nel terzo caso, il riferimento alla funzione anonima viene riassegnato ad ogni iterazione. Nel quarto caso, l'intera definizione di funzione è invariata, ma viene ancora ripetutamente definita come se fosse nuova (a meno che non fosse [[promoted]] dal compilatore) e quindi non sia statica. Pertanto, sebbene sembrino essere semplicemente [[Multiple identifier event listers]], in entrambi i casi ogni iterazione creerà invece un nuovo listener con il proprio riferimento univoco alla funzione del gestore. Tuttavia, poiché la definizione della funzione stessa non cambia, la funzione SAME può ancora essere chiamata per ogni listener duplicato (specialmente se il codice viene ottimizzato).

Anche in entrambi i casi, poiché il riferimento alla funzione è stato mantenuto ma ripetutamente ridefinito con ogni aggiunta, l'istruzione remove di sopra può ancora rimuovere un listener, ma ora solo l'ultimo aggiunto.

// Solo a scopo illustrativo: nota che "MISTAKE" di [j] per [i] causando così l'associazione di tutti gli eventi desiderati allo STESSO elemento

// Case 3
for (var i = 0, j = 0 ; i < els.length ; i++) {
  /* do lots of stuff with */
  els[j].addEventListener("click", processEvent = function(e){/* do something */}, false);
}

// Case 4
for (var i = 0, j = 0 ; i < els.length ; i++) {
  /* do lots of stuff with j */
  function processEvent(e){/* do something */};
  els[j].addEventListener("click", processEvent, false); 
}

Miglioramento delle prestazioni di scorrimento con i listeners passivi

Secondo la specifica, il valore predefinito per l'opzione passive è sempre falso. Tuttavia, questo introduce il potenziale per gli ascoltatori di eventi che gestiscono determinati eventi di tocco (tra gli altri) per bloccare il thread principale del browser mentre sta tentando di gestire lo scrolling, con conseguente enorme riduzione delle prestazioni durante la gestione dello scorrimento.

Per evitare questo problema, alcuni browser (in particolare, Chrome e Firefox) hanno modificato il valore predefinito dell'opzione  passive in true per gli eventi touchstart e touchmove events sui nodi a livello del documento Window, Document, e Document.body. Questo impedisce al listener di eventi di essere chiamato, quindi non può bloccare il rendering della pagina mentre l'utente sta scorrendo.

Note: Vedi la tabella di compatibilità qui sotto se hai bisogno di sapere quali browser (e / o quali versioni di quei browser) implementano questo comportamento alterato.

Puoi sovrascrivere questo comportamento impostando esplicitamente il valore di passive a false, come mostrato qui:

/* Feature detection */
var passiveIfSupported = false;

try {
  window.addEventListener("test", null, Object.defineProperty({}, "passive", { get: function() { passiveIfSupported = { passive: true }; } }));
} catch(err) {}

window.addEventListener('scroll', function(event) {
  /* do something */
  // can't use event.preventDefault();
}, passiveIfSupported );

Nei browser meno recenti che non supportano il parametro options su addEventListener(), il tentativo di utilizzarlo impedisce l'utilizzo dell'argomento  useCapture senza utilizzare correttamente il rilevamento delle funzionalità.

You don't need to worry about the value of passive for the basic scroll event. Since it can't be canceled, event listeners can't block page rendering anyway.

Specifiche

Specificazione Stato Commento
DOM
The definition of 'EventTarget.addEventListener()' in that specification.
Living Standard  
DOM4
The definition of 'EventTarget.addEventListener()' in that specification.
Obsolete  
Document Object Model (DOM) Level 2 Events Specification
The definition of 'EventTarget.addEventListener()' in that specification.
Obsolete Definizione inziale

Compatibilità con i browser

Update compatibility data on GitHub
DesktopMobile
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidEdge MobileFirefox for AndroidOpera for AndroidSafari on iOSSamsung Internet
Basic supportChrome Full support 1
Notes
Full support 1
Notes
Notes Before Chrome 49, the type and listener parameters were optional.
Edge Full support 12Firefox Full support 1IE Full support 9
Full support 9
No support 6 — 11
Notes Alternate Name
Notes Older versions of IE supported an equivalent, proprietary EventTarget.attachEvent() method.
Alternate Name Uses the non-standard name: attachEvent
Opera Full support 7Safari Full support 1WebView Android Full support 1
Notes
Full support 1
Notes
Notes Before Chrome 49, the type and listener parameters were optional.
Chrome Android Full support 18
Notes
Full support 18
Notes
Notes Before Chrome 49, the type and listener parameters were optional.
Edge Mobile Full support YesFirefox Android Full support 4Opera Android Full support 7Safari iOS Full support 1Samsung Internet Android Full support Yes
useCapture parameter made optionalChrome Full support 1Edge Full support YesFirefox Full support 6IE Full support 9Opera Full support 11.6Safari Full support YesWebView Android Full support 1Chrome Android Full support 18Edge Mobile Full support YesFirefox Android Full support 6Opera Android Full support 11.6Safari iOS Full support YesSamsung Internet Android Full support Yes
Form with options object supported (third parameter can be either options or a Boolean, for backwards compatibility)Chrome Full support 49Edge Full support YesFirefox Full support 49IE No support NoOpera Full support YesSafari Full support 10WebView Android Full support 49Chrome Android Full support 49Edge Mobile Full support YesFirefox Android Full support 49Opera Android Full support YesSafari iOS Full support 10Samsung Internet Android Full support 5.0
options: capture optionChrome Full support 52Edge Full support YesFirefox Full support YesIE No support NoOpera Full support YesSafari Full support YesWebView Android Full support 52Chrome Android Full support 52Edge Mobile Full support YesFirefox Android Full support YesOpera Android Full support YesSafari iOS Full support YesSamsung Internet Android Full support 6.0
options: once optionChrome Full support 55Edge Full support YesFirefox Full support 50IE No support NoOpera Full support 42Safari Full support YesWebView Android Full support 55Chrome Android Full support 55Edge Mobile Full support YesFirefox Android Full support 50Opera Android Full support 42Safari iOS Full support YesSamsung Internet Android Full support 6.0
options: passive optionChrome Full support 51Edge Full support YesFirefox Full support YesIE No support NoOpera Full support YesSafari Full support YesWebView Android Full support 51Chrome Android Full support 51Edge Mobile Full support YesFirefox Android Full support YesOpera Android Full support YesSafari iOS Full support YesSamsung Internet Android Full support 5.0
options: passive option defaults to true for touchstart and touchmove eventsChrome Full support 55Edge No support NoFirefox Full support 61IE No support NoOpera ? Safari No support NoWebView Android Full support 55Chrome Android Full support 55Edge Mobile No support NoFirefox Android Full support 61Opera Android ? Safari iOS No support NoSamsung Internet Android Full support 6.0

Legend

Full support  
Full support
No support  
No support
Compatibility unknown  
Compatibility unknown
See implementation notes.
See implementation notes.
Uses a non-standard name.
Uses a non-standard name.

Vedi anche

Tag del documento e collaboratori

Hanno collaborato alla realizzazione di questa pagina: IsibisiDev, akmur, gitact, vindega, teoli, khalid32, loris94, Samuele, DaViD83
Ultima modifica di: IsibisiDev,