Lo siguiente funciona bien y mi detector de eventos obtiene el evento personalizado porque envía el evento desde la ventana y mi detector de eventos está escuchando para loading en la ventana, todo bien.
const MyLib = mylib(); function mylib() { const res = { init: (data) => { let loading = new CustomEvent('loading', {detail: { loading: true }}); window.dispatchEvent(loading); } } return res; }detector de eventos
window.addEventListener('loading', handleLoading); ¿Cómo puedo cambiarlo a MyLib.addEventListener en lugar de window.addEventListener ?
y..
window.dispatchEvent(loading); a MyLib.dispatchEvent(loading);
El error que recibo es TypeError: MyLib.addEventListener is not a function
La respuesta a continuación funciona en una clase, pero me gustaría saber si esto es posible sin usar una clase.
Se puede utilizar proxy para lograr los requisitos.
Aquí hay un fragmento que envuelve el objeto MyLib original en un Proxy , cuya trampa de get se activa al acceder a addEventListener o dispatchEvent .
function mylib() { const res = { init: (data) => { let loading = new CustomEvent('loading', {detail: { loading: true }}); MyLib.dispatchEvent(loading); } } return res; } const MyLib = new Proxy(mylib(), { get: function(target, prop) { if (prop === `addEventListener`) { return (...args) => window.addEventListener(...args); } if (prop === `dispatchEvent`) { return (...args) => window.dispatchEvent(...args); } return target[prop]; } }); MyLib.addEventListener('loading', () => { console.log("Hello world !!!") }); MyLib.init();Para enviar y escuchar eventos en un objeto, el objeto deberá heredar de la interfaz EventTarget .
class MyLib extends EventTarget { constructor() { super(); } init(data) { let loading = new CustomEvent('loading', { detail: { loading: true } }); this.dispatchEvent(loading); } } // somewhere myLib is an instantiation of MyLib useEffect(() => { myLib.addEventListener('loading', handleLoading); return () => { myLib.removeEventListener('loading', handleLoading); }; }, []);