2013-10-19 14 views
74

Desidero rimuovere tutti i listener di eventi di un tipo specifico che sono stati aggiunti utilizzando addEventListener(). Tutte le risorse che sto vedendo stai dicendo bisogno di fare questo:Rimuovi tutti gli ascoltatori di eventi di tipo specifico

elem.addEventListener('mousedown',specific_function); 
elem.removeEventListener('mousedown',specific_function); 

ma voglio essere in grado di cancellarlo senza sapere quello che è attualmente, in questo modo:

elem.addEventListener('mousedown',specific_function); 
elem.removeEventListener('mousedown'); 

risposta

150

Questo è non è possibile senza intercettare chiamate addEventListener e tenere traccia degli ascoltatori o utilizzare una libreria che consente purtroppo tali funzionalità. Sarebbe stato se la raccolta degli ascoltatori fosse accessibile ma lo feature wasn't implemented.

La cosa più vicina che si può fare è rimuovere tutti gli ascoltatori clonando l'elemento, che non clonerà la raccolta degli ascoltatori.

Nota: questo rimuoverà anche gli ascoltatori sui figli dell'elemento.

var el = document.getElementById('el-id'), 
    elClone = el.cloneNode(true); 

el.parentNode.replaceChild(elClone, el); 
+1

geniale, grazie) – Simcha

+1

brillante, i mustve cercato questo 100 volte, e questa è la prima volta Ho visto qualcosa di così elegante, e la parte migliore, pura js. la sua causa di uso improprio di librerie che devo usare questo. ancora una volta, geniale! –

+0

Penso che tu stia partendo dal presupposto che il nodo sostituito (con i listener di eventi) sarà spazzato via. Potresti imbatterti in strani problemi se non è questo il caso. – Renaud

0

Si potrebbe alternativamente sovrascrivere il metodo 'yourElement.addEventListener()' e utilizzare il metodo '.Applicare()' per eseguire l'ascoltatore come normale, ma intercettando la funzione nel processo. Ad esempio:

<script type="text/javascript"> 

    var args = []; 
    var orginalAddEvent = yourElement.addEventListener; 

    yourElement.addEventListener = function() { 
     //console.log(arguments); 
     args[args.length] = arguments[0]; 
     args[args.length] = arguments[1]; 
     orginalAddEvent.apply(this, arguments); 
    }; 

    function removeListeners() { 
     for(var n=0;n<args.length;n+=2) { 
      yourElement.removeEventListener(args[n], args[n+1]); 
     } 
    } 

    removeListeners(); 

</script> 

Questo script deve essere eseguito al caricamento della pagina o potrebbe non intercettare tutti i listener di eventi.

Assicurarsi di rimuovere la chiamata 'removeListeners()' prima dell'uso.

-1

Rimuovere tutti gli ascoltatori di elemento da linea uno js:

element.parentNode.innerHTML += ''; 
+0

Funzionerebbe solo senza effetti collaterali se l'elemento era l'unico figlio. – plalx

0

So che questo è vecchio, ma ho avuto un problema simile con risposte reali, in cui ho voluto per rimuovere tutti gli eventi "keydown" ascoltatori dal documento. Invece di rimuoverli, ho calpestato l'addEventListener di ignorarli prima che fossero anche aggiunto, simile a Toms risposta di cui sopra, con l'aggiunta di questo prima di qualsiasi altro script vengono caricati .:

<script type="text/javascript"> 
    var current = document.addEventListener; 
    document.addEventListener = function (type, listener) { 
     if(type =="keydown") 
     { 
      //do nothing 
     } 
     else 
     { 
      var args = []; 
      args[0] = type; 
      args[1] = listener; 
      current.apply(this, args); 
     } 
    }; 
</script> 
6

Se il vostro unico obiettivo rimuovendo gli ascoltatori è quello di impedire loro di esecuzione, è possibile aggiungere un listener di eventi per la finestra di cattura e cancellazione di tutti gli eventi del tipo specificato:

window.addEventListener(type, function (event) { 
    event.stopPropagation(); 
}, true); 

Passando true per il terzo parametro fa sì che l'evento da catturare durante la discesa . Fermare la propagazione significa che l'evento non raggiunge mai gli ascoltatori che lo stanno ascoltando.

0

È necessario eseguire l'override di EventTarget.prototype.addEventListener per creare una funzione trap per la registrazione di tutte le chiamate di 'add listener'. Qualcosa di simile a questo:

var _listeners = []; 

EventTarget.prototype.addEventListenerBase = EventTarget.prototype.addEventListener; 
EventTarget.prototype.addEventListener = function(type, listener) 
{ 
    _listeners.push({target: this, type: type, listener: listener}); 
    this.addEventListenerBase(type, listener); 
}; 

Quindi è possibile costruire un EventTarget.prototype.removeEventListener s:

EventTarget.prototype.removeEventListeners = function(targetType) 
{ 
    for(var index = 0; index != _listeners.length; index++) 
    { 
     var item = _listeners[index]; 

     var target = item.target; 
     var type = item.type; 
     var listener = item.listener; 

     if(target == this && type == targetType) 
     { 
      this.removeEventListener(type, listener); 
     } 
    } 
} 

In ES6 è possibile utilizzare un simbolo, per nascondere la funzione originale e l'elenco di tutti aggiunto listener direttamente nel self dell'oggetto istanziato.

(function() 
{ 
    let target = EventTarget.prototype; 
    let functionName = 'addEventListener'; 
    let func = target[functionName]; 

    let symbolHidden = Symbol('hidden'); 

    function hidden(instance) 
    { 
     if(instance[symbolHidden] === undefined) 
     { 
      let area = {}; 
      instance[symbolHidden] = area; 
      return area; 
     } 

     return instance[symbolHidden]; 
    } 

    function listenersFrom(instance) 
    { 
     let area = hidden(instance); 
     if(!area.listeners) { area.listeners = []; } 
     return area.listeners; 
    } 

    target[functionName] = function(type, listener) 
    { 
     let listeners = listenersFrom(this); 

     listeners.push({ type, listener }); 

     func.apply(this, [type, listener]); 
    }; 

    target['removeEventListeners'] = function(targetType) 
    { 
     let self = this; 

     let listeners = listenersFrom(this); 
     let removed = []; 

     listeners.forEach(item => 
     { 
      let type = item.type; 
      let listener = item.listener; 

      if(type == targetType) 
      { 
       self.removeEventListener(type, listener); 
      } 
     }); 
    }; 
})(); 

È possibile verificare questo codice con questo piccolo snipper:

document.addEventListener("DOMContentLoaded", event => { console.log('event 1'); }); 
document.addEventListener("DOMContentLoaded", event => { console.log('event 2'); }); 
document.addEventListener("click", event => { console.log('click event'); }); 

document.dispatchEvent(new Event('DOMContentLoaded')); 
document.removeEventListeners('DOMContentLoaded'); 
document.dispatchEvent(new Event('DOMContentLoaded')); 
// click event still works, just do a click in the browser 
Problemi correlati