资讯专栏INFORMATION COLUMN

利用DOM0级事件模拟简单的事件系统

Mr_zhang / 2404人阅读

摘要:但是这样并不能实际使用,因为用来保存事件的数组当前是作为一个全局变量。请先使用绑定事件。在使用时传入三个参数,元素,事件类型,回调方法,即可。

让我们回到还没有DOM2级事件方法的年代,那时候,我们想给某元素绑定一个事件方法时,是这样做的:

javascriptvar ele=document.getElementById("main");
ele.onclick=function(){
    console.log("做一件事");
}

这就是DOM0级事件方法,我们需要用XXX.onYYY=ZZZ这种形式来绑定事件,当点击元素时,会输出“做一件事”,恩,很理想。

接下来,当我们希望在点击该元素的时候再做另一件事怎么办呢?下面这样:

javascriptele.onclick=function(){
   console.log("做第二件事");
}

这样肯定不行,因为我们是希望点击时既输出“做一件事”,又要输出“做第二件事”。而这样的话后面的方法将前面的覆盖掉了,因为XXX.onYYY=ZZZ只能给元素的某个事件类型(如例子中的click事件)绑定一个方法ZZZ;这个问题难不到我们,既然这样,那我们就把要做的事情全都放在ZZZ里不就行了么;

javascriptfunction fn1(){
    console.log("做一件事");
}
function fn2(){
   console.log("做第二件事");
}
ele.onclick=function(){
    fn1();
    fn2();
}

接下来,挑战来了,那如果我们是希望在点击元素时做100件不同的事情呢?难道也是这样用XXX.onYYY=ZZZ形式,将100个方法都在ZZZ里依次执行吗?显然这是很笨的方法;动一下脑筋,很快想到另一个解决方案:
明确以下需求,我们是希望在点击事件发生时,执行多个方法,而具体有多少个,一开始时不明确的,那么我们可以用一个数组来保存所有的回调方法;当点击发生时,执行一个方法,在这个方法中依次执行数组中的回调方法。

javascriptvar arr=[];
ele.onclick=function(){
    for(var i=0;i

这样的话,当我们需要给元素点击事件添加更多的方法时,直接往数组arr中push更多的回调方法就行了,甚至当我们希望去掉某个方法,也可以通过删除数组中的某项来完成。
但是这样并不能实际使用,因为用来保存事件的数组当前是作为一个全局变量。为了持久化保存这个数组,我们可以这样,将这个数组定义为元素节点对象的某一个属性,就像下面这样:

javascriptele.eventList=[];
ele.onclick=function(){
    for(var i=0;i

以上代码只是针对click事件,在实际运用时,有各种不同的事件类型;在某个类型事件触发时,需要执行所有绑定到该类型事件的方法,因此,针对每个事件类型,都要采用一个数组来保存相应回调方法。
另外,为了在某类型事件触发时,找到针对与该事件类型的所有方法并执行,我们可以将这个数组直接以事件类型名称命名;
然后考虑将以上方法用一个函数封装起来:如下

javascriptfunction bind(ele,ev,callback){
    if(!ele.ev){
        ele.ev=[];//直接将保存某个事件类型所有回调方法的数组命名为事件类型
        ele["on"+ev]=function(){
            for(var i=0;i

为了防止重复绑定,在将回调函数push进事件队列数组时,首先需要判断被绑定的回调是否已经存在于事件队列中;

javascriptfunction bind(ele,ev,callback){
    if(!ele.ev){
        ele.ev=[];
        ele["on"+ev]=function(){ //只需要绑定一次
            for(var i=0;i

而相应unbind方法,只需要将需要解绑的回调函数从相应的函数队列中删除即可;
另外还有以下一个问题:上述这种情况下,绑定了几个类型的事件,就会给ele多添加几个属性,命名空间污染极其严重;所以采用的方案是在元素上只添加一个属性(如_event),然后所有的事件队列全都扩展在这个属性上。

全部代码如下:

完整版代码
javascriptfunction bind(ele,ev,callback){
    if(!ele._event){
        ele._event={};
    }
    if(!ele._event[ev]){
        ele._event[ev]=[];
        ele["on"+ev]=function(e){
            e=e||window.event;

            var eList=ele._event[ev];
            for(var i=0;i

在使用时传入三个参数,元素,事件类型,回调方法,即可。解绑时传入同样的三个参数;这个简单的方案解决了以下问题:

this关键字指向问题

重复绑定问题

执行顺序问题

  

以上,我们就完成了一个粗糙的事件系统,它的思想很类似于Dean Edward在其发布的addEvent.js中的实现方式;

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

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

相关文章

  • 原生js之DOM事件相关

    摘要:而由于级标准中并没有定义事件相关的内容,所以事件级别只包括级,级和级三种。此属性返回当前事件所绑定的对象。自定义事件可以绑定到任意元素上,此处选择只是为了演示方便。 前端学习的东西有很多,现代前端开发,前端工程化的东西要懂,基础的原生js也要懂,毕竟,框架都是有生命周期的,更替非常快,然而却有这么一个框架,它是最轻量的前端框架,每个浏览器都内置,它叫vanilla.js。好吧,其实va...

    learning 评论0 收藏0
  • 整理DOM事件相关知识点

    摘要:事件相关内容当用户与浏览器发生的一些交互时如果希望去获得用户行为就需要借助事件来完成事件部分内容在中重要性不言而喻罗列需要了解与事件相关的知识如下这也是面试中遇到的问题事件的级别事件模型事件流事件处理程序描述事件捕获冒泡的具体流程对象常见的 DOM事件相关内容 当用户与浏览器发生的一些交互时, 如果希望去获得用户行为, 就需要借助事件来完成. 事件部分内容在 JS中重要性不言而喻. ...

    shenhualong 评论0 收藏0
  • 整理DOM事件相关知识点

    摘要:事件相关内容当用户与浏览器发生的一些交互时如果希望去获得用户行为就需要借助事件来完成事件部分内容在中重要性不言而喻罗列需要了解与事件相关的知识如下这也是面试中遇到的问题事件的级别事件模型事件流事件处理程序描述事件捕获冒泡的具体流程对象常见的 DOM事件相关内容 当用户与浏览器发生的一些交互时, 如果希望去获得用户行为, 就需要借助事件来完成. 事件部分内容在 JS中重要性不言而喻. ...

    red_bricks 评论0 收藏0
  • 读书笔记(05) - 事件 - JavaScript高程序设计

    摘要:而事件分为个级别级事件处理程序,级事件处理程序和级事件处理程序。级中没有规范事件的相关内容,所以没有级事件处理。 showImg(https://segmentfault.com/img/bVburYR?w=499&h=400); HTML依托于JavaScript来实现用户与WEB网页之间的动态交互,接收用户操作并做出相应的反馈,而事件在此间则充当桥梁的重要角色。 日常开发中,经常会...

    tinylcy 评论0 收藏0

发表评论

0条评论

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