Vous devez remplacer EventTarget.prototype.addEventListener pour construire une fonction trap pour enregistrer tous les appels 'ajouter un écouteur'. Quelque chose comme cela :
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);
};
Ensuite, vous pouvez construire un EventTarget.prototype.removeEventListeners:
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);
}
}
}
En ES6, vous pouvez utiliser un symbole pour masquer la fonction originale et la liste de tous les écouteurs ajoutés directement dans l'objet instancié lui-même.
(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);
}
});
};
})();
Vous pouvez tester ce code avec ce petit extrait :
document.addEventListener("DOMContentLoaded", event => { console.log('événement 1'); });
document.addEventListener("DOMContentLoaded", event => { console.log('événement 2'); });
document.addEventListener("click", event => { console.log('événement de clic'); });
document.dispatchEvent(new Event('DOMContentLoaded'));
document.removeEventListeners('DOMContentLoaded');
document.dispatchEvent(new Event('DOMContentLoaded'));
// l'événement de clic fonctionne toujours, il suffit de cliquer dans le navigateur