写在前面,这篇文章会发表在Blog、掘金、segmentfault、知乎等,如果这篇文章对你有帮助,记得获取我的个人技术博客项目我哦星。为什么写这篇文章?你可能已经做了一段时间的网页开发,你有没有想过以下问题?为什么div元素甚至所有的html元素都可以使用addEventListener来添加事件?为什么每个DOM节点都有parentNode、firstChild、nodeType等属性?为什么每个DOM元素都有className、classList、innerHTML等属性?为什么有些DOM元素会有accessKey、contentEditable、isContentEditable等属性?为什么每个DOM元素都有onclick、ondblclick、ondrag等属性?这篇文章就是要回答这些简单而不“简单”的问题。EventTarget定义EventTarget是由可以接收事件并为其创建侦听器的对象实现的接口。作用Element、document和window是最常见的事件目标,但其他对象也可以是事件目标,例如XMLHttpRequest、AudioNode、AudioContext等。许多事件目标(包括元素、文档和窗口)也支持通过onXXX(如onclick)属性和属性设置事件处理程序。该接口的EventTarget.addEventListener()方法为EventTarget上的特定事件类型注册事件处理程序。EventTarget.removeEventListener()从EventTarget中移除一个事件侦听器。EventTarget.dispatchEvent()向此EventTarget分派一个事件。我们实现EventTargetvarEventTarget=function(){this.listeners={};};EventTarget.prototype.listeners=null;EventTarget.prototype.addEventListener=function(type,callback){if(!(typeinthis.listeners)){this.listeners[type]=[];}this.listeners[type].push(callback);};EventTarget.prototype.removeEventListener=function(type,callback){if(!(typeinthis.listeners)){return;}varstack=this.listeners[type];对于(vari=0,l=stack.length;i
