È 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
fonte
2017-11-05 00:39:21
geniale, grazie) – Simcha
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! –
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