Javascript 如何';addEventListener‘幕后工作?

Javascript 如何';addEventListener‘幕后工作?,javascript,event-listener,Javascript,Event Listener,所以,我有这种好奇心已经有很长一段时间了。我想知道,addEventListener在幕后是如何工作的。我知道它是做什么的,但我就是不知道它是怎么做的 我已经检查了许多链接和资源,是一个最接近我所寻找的,但仍然没有成功 为了澄清我真正想要的是什么,我想知道如何创建自己的addEventListener函数,该函数将第一个参数作为事件名称,第二个参数作为接受eventArgs参数的回调。addEventListener将句柄与html DOM节点绑定。它接受要附加的事件和一个回调函数。如果要向DO

所以,我有这种好奇心已经有很长一段时间了。我想知道,
addEventListener
在幕后是如何工作的。我知道它是做什么的,但我就是不知道它是怎么做的

我已经检查了许多链接和资源,是一个最接近我所寻找的,但仍然没有成功


为了澄清我真正想要的是什么,我想知道如何创建自己的
addEventListener
函数,该函数将第一个参数作为事件名称,第二个参数作为接受
eventArgs
参数的回调。

addEventListener将句柄与html DOM节点绑定。它接受要附加的事件和一个回调函数。

如果要向DOM添加自定义事件,我认为这是不可能的。至少我不知道有任何规范支持这一点。有一个自定义元素规范,允许您创建自己的元素规范。在此过程中,您可以检查哪些事件可能被触发。但是,您可以在DOM之外执行相同的概念:

var callbacks = [];
function addToEventListener(callback) {
    callbacks.push(callback);
}

function triggerMyEvent(payload) {
    callbacks.forEach(function(cb){
        cb(payload);
    });
}

addToEventListener(function(p){
    console.log(p);
});

triggerMyEvent({testValue:true});

注意:上面使用globals,这不是一个好的实践。我不建议这样做,但为了这篇文章的简洁,我选择使用globals。想法是一样的。

这将是事件调度系统的简单示例

class BusEvent {
    eventName = null;
    callbacks = [];

    constructor(eventName) {
        this.eventName = eventName;
    }

    register(callback) {
        this.callbacks.push(callback);
    }

    unregister(callback) {
        const index = this.callbacks.indexOf(callback);
        if (index > -1) {
            this.callbacks.splice(index, 1);
        }
    }

    execute(data) {
        const callbacks = this.callbacks.slice(0);
        callbacks.forEach((callback) => {
            callback(data);
        });
    }
}

class MessageBus {
    constructor() {
        this.events = {};
    }

    dispatch(eventName, data) {
        const event = this.events[eventName];
        if (event) {
            event.execute(data);
        }
    }

    on(eventName, callback) {
        let event = this.events[eventName];
        if (!event) {
            event = new BusEvent(eventName);
            this.events[eventName] = event;
        }
        event.register(callback);
    }

    off(eventName, callback) {
        const event = this.events[eventName];
        if (event && event.callbacks.indexOf(callback) > -1) {
            event.unregister(callback);
            if (event.callbacks.length === 0) {
                delete this.events[eventName];
            }
        }
    }
}
用法:

const messageBus = new MessageBus();
messageBus.on('ReceiveData', (data) => {
    console.log(data);
})

messageBus.dispatch('ReceiveData', { name: 'Ted' });
// console logs { name: 'Ted' }

据我所知,JS有一种观察者,这是GoF(四人帮)的设计模式,你可以阅读更多。观察者将一直等待状态更改,然后当状态更改时,将调用回调通知所有对象。下面的UML将让您了解它是如何工作的


所以,我确实认为JS是这样工作的,但不是所有对象都是相同的,而是每个对象都有一个自定义回调,或者多个回调。我不太确定这一点,但应该是这样工作的。我没有在网上找到任何东西,但是这里谈到了它

addEventListener
是浏览器提供的用于侦听DOM事件的API。由于事件处理和处理是浏览器DOM模型的一部分,其内部无法从JavaScript端访问(至少对于普通浏览器是如此),因此,如果不在某一点上使用
addEventListener
,就无法实现您自己的
addEventListener
。在内部,它如何知道何时,如果发生鼠标单击,那么应该调用此函数吗?它应该有某种类型的
侦听器
线程,可以持续侦听任何事件。浏览器供应商如何详细解决该任务是高度依赖于实现的。遗憾的是,这样一个有趣的问题被搁置了。问题是JS是由编译器编译的,每个浏览器中的编译器都不同。因此,魔法实际上发生在编译器的内部C或C++代码中。你可以检查ChelpCalpUng. IgorBykov是有趣的,但是它是没有答案的,如果它有一个特定的浏览器,比如Chalor,关于它的C++代码,那就不同了,但是它不是。即使是关于创建自定义事件,它也可以作为一个副本关闭,例如,这如何回答这个问题?您可以使用创建自定义事件,并在您想要的任何DOM元素上触发它们。谢谢。它澄清了我的许多疑问,如果不是全部的话。没问题,很高兴能得到帮助。但正如我所说,我不确定JS事件监听器是否可以这样工作,但应该是类似的。