资讯专栏INFORMATION COLUMN

实现一个EventTarget类

Pocher / 1845人阅读

摘要:是一个由可以接收事件的对象实现的接口,并且可以为它们创建侦听器。方法节在上注册特定事件类型的事件处理程序。将事件分派到此。代码的其他方法节扩展,供实现的事件目标使用以实现属性。级中是一般化的变动事件。

EventTarget

EventTarget是一个由可以接收事件的对象实现的接口,并且可以为它们创建侦听器。

Elementdocumentwindow 是最常见的事件目标,但是其他对象也可以是事件目标,比如XMLHttpRequestAudioNodeAudioContext 等等。

许多事件目标(包括元素,文档和 window)还支持通过 on... 属性和属性设置事件处理程序。

构造函数节

EventTarget()

创建一个新的 EventTarget 对象实例。

方法节

EventTarget.addEventListener()

在EventTarget上注册特定事件类型的事件处理程序。

EventTarget.removeEventListener()

EventTarget中删除事件侦听器。

EventTarget.dispatchEvent()

将事件分派到此EventTarget。

Mozilla chrome 代码的其他方法节

Mozilla扩展,供JS实现的事件目标使用以 实现 on* 属性。另见 WebIDL bindings 绑定。

void setEventHandler(DOMString type, EventHandler handler)

EventHandler getEventHandler(DOMString type)

示例节 EventTarget 的简单实现节
function EventTarget() {
    this.listeners = {};
}

Object.assign(EventTarget.prototype, {
    // listeners: null,
    // prefix:"on",
    addEventListener: function (type, callback) {
        if (!(type in this.listeners)) {
            this.listeners[type] = [];
        }
        this.listeners[type].push(callback);
    },
    removeEventListener: function (type, callback) {
        if (type in this.listeners) {
            let stack = this.listeners[type];
            let index = stack.indexOf(callback);
            console.log(index);
            //可能会添加多个
            while (index !== -1) {
                stack.splice(index, 1);
                index = stack.indexOf(callback);
            }
        }
    },
    dispatchEvent: function (event) {
        if (event.type in this.listeners) {
            let stack = this.listeners[event.type];
            event.target = this;
            stack.forEach(callback => {
                callback.call(this,event);
            })
        }
    }
});


let target = new EventTarget();
let remove = (e) => {console.log(e)};
target.addEventListener("test",remove);
target.addEventListener("test",remove);
target.addEventListener("test",(e) => {console.log(e)});
target.removeEventListener("test",remove);
target.dispatchEvent({type:"test"});

当单击这个例子中的按钮时, this 和 currentTarget 都等于 document.body,因为事件处理程 序是注册到这个元素上的。然而, target 元素却等于按钮元素,因为它是 click 事件真正的目标。由 于按钮上并没有注册事件处理程序,结果 click 事件就冒泡到了 document.body,在那里事件才得到 了处理。

document.body.onclick = function(event){
    alert(event.currentTarget === document.body); //true
    alert(this === document.body); //true
    alert(event.target === document.getElementById("myBtn")); //true
};

所有问事件的target和currentTarget区别的问题,都是在变相的问事件委托。

因为子元素将事件委托到父级的时候,event的target指向的还是子元素,而currentTarget指的是父元素

  • w
  • m
  • x
//子元素将事件委托给了父元素 document.querySelector("ul").addEventListener("click",(e) => { let text = e.target.innerText || e.target.textContent; swicth(text){ case "w":{ console.info("this first li"); break; } case "m":{ console.info("this second li"); break; } case "x":{ console.info("this third li"); break; } default:{ new Error("No such Element") } } },false)

事件模拟

事件创建

参数事件类型字符串UIEvents

document.createEvent(EventTypeString)

UIEvents:一般化的 UI 事件。 鼠标事件和键盘事件都继承自 UI 事件。 DOM3 级中是 UIEvent;

MouseEvents:一般化的鼠标事件。 DOM3 级中是 MouseEvent;

MutationEvents:一般化的 DOM 变动事件。 DOM3 级中是 MutationEvent;

HTMLEvents:一般化的 HTML 事件。没有对应的 DOM3 级事件(HTML 事件被分散到其他类 别中);

KeyboardEvents :DOM3级中添加

var btn = document.getElementById("myBtn");
//创建事件对象
var event = document.createEvent("MouseEvents");
//初始化事件对象
event.initMouseEvent("click", true, true, document.defaultView, 0, 0, 0, 0, 0,false, false, false, false, 0, null);
//添加事件监听
btn.addEventListener("click",e => console.log(e))
//触发事件dispatch中动态将this绑定到event.target上,也就是btn
btn.dispatchEvent(event);
//执行监听函数
//e

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/101696.html

相关文章

  • 如何形成一个完整的HTML对象

    摘要:定义是一个由可以接收事件的对象实现的接口,并且可以为它们创建侦听器。重点分割线只有通过上面的继承关系,我们得到的元素才是一个完整的对象,我们才能为它设置获取属性绑定事件添加样式类等操作。 写在前面,本文将同步发布于Blog、掘金、segmentfault、知乎等处,如果本文对你有帮助,记得为我得到我的个人技术博客项目给个star哦。 为何写这篇文章? 你可能做Web开发已经有一段时间,...

    freewolf 评论0 收藏0
  • 自定义事件

    摘要:介绍自定义事件之前,首先要介绍一种设计模式观察者模式。自定义事件背后的概念是创建一个管理事件的对象,让其他对象监听这些事件。问自定义事件的认知逻辑是什么答咳咳应该是观察者模式吧,能力有限,具体的描述以后补上。 介绍自定义事件之前,首先要介绍一种设计模式--观察者模式。 事件是一种叫做观察者的设计模式,是一种创建松散耦合代码的技术。 观察者模式有两类对象组成:主体和观察者。主体负责发布...

    陆斌 评论0 收藏0
  • javascript基础学习

    摘要:预解释变量和函数的预解释只发生在当前的作用于中中内存的分类栈内存用来提供一个代码指定的环境作用域全局作用域和局部作用域堆内存用来存储引用类型的值对象存储的是键值对,函数储存的是字符串函数执行的时候形成一个私有作用域有形参给形参赋值,形参也 预解释 变量和函数的预解释只发生在当前的作用于中 js中内存的分类 栈内存:用来提供一个js代码指定的环境 —>作用域(全局作用域和局部作用域...

    魏明 评论0 收藏0
  • 有关DOM Event事件和自定义Event相关文档文章介绍速记

    摘要:搞清之间的关系指的事件绑定时的对象指的事件发生所在的对象,例如你的把事件可以绑在父元素上,点击子元素,此时指的是父元素,指的是你点击的子元素。是一个非标准属性,是老对于的实现,指的事件发生所在的对象。 搞清Event.currentTarget、Event.target、Event.srcElement之间的关系 Event.currentTarget: https://develo...

    callmewhy 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<