美文网首页
Javascript中的事件流(IE和W3C的区别)和事件委托

Javascript中的事件流(IE和W3C的区别)和事件委托

作者: 胡拉圈 | 来源:发表于2019-02-27 13:56 被阅读0次

事件流是用来描述页面接收事件的顺序。目前存在的两种基本的事件流为事件冒泡和事件捕获

事件冒泡

即事件应该从嵌套层次最深的节点(目标元素节点)冒泡到较为不具体的节点(Document对象),所有的现代浏览器都支持事件冒泡,但是在IE5.5以及之前的版本事件冒泡会跳过html标签,也就是说会直接从body冒泡到Document,而在IE9,firefox,chrome和safari浏览器则会将事件一直冒泡到window对象上。

       <!DOCUMENT html>
       <html>
           <head>
               <title>HTML</title>
           </head>
           <body>
               <p id="click">Click</p>
           </body>  
       </html>

如果点击了p标签的元素,事件就会向上冒泡,依次为<p>,<body>,<html>,<Document>

事件捕获

即事件应该从不具体的节点先接收,然后再向更深层次的节点传播,以上述代码为例,如果是事件捕获,则Document对象会先捕获到事件,然后再沿着DOM树向下到html标签,body标签,最后到达p标签

IE事件流

1、IE事件流只支持事件冒泡,不支持事件捕获
2、IE事件流可以通过可以通过attachEvent()和detachEvent()来添加和删除事件,这两个方法只接受两个参数,依次为 (target,handler),事件类型("on"+事件类型),事件处理函数,需要注意的一点是在使用detachEvent()方法删除事件时,参数要和创建事件时的参数相同,即第二个参数不支持通过匿名函数来创建,否则会被视为不是同一个方法。
    const btn = document.getElementById("button");
    btn.attachEvent("onclick",function(){
          console.log("click");
    })

     btn.detachEvent("onclick",function(){
           console.log("click");
     })
     //删除失败,尽管两个匿名函数一样,但是在处理时会被识别为两个不同的函数对象
3、IE事件中的this指向的是window对象而不是目标元素对象,是因为在使用attachEvent()创建事件时,事件处理程序运行的作用于不是目标元素所在的作用域,而是在全局作用域中运行,所以this指向的是window而不是目标元素
4、在IE事件流中,如果为一个元素顺序绑定多个事件,事件执行的顺序是按照逆序执行的。
      const btn = document.getElementById("button");
      btn.attachEvent("onclick",function(){
          console.log("one");
      })

      btn.attachEvent("onclick",function(){
          console.log("two");
      })

       btn.attachEvent("onclick",function(){
          console.log("three");
      })

      //出发事件的运行结果为
      //three
      //two
      //one
5、IE事件中可以通过returnValue属性来阻止事件的默认行为,即将window.event.returnValue设置为false就可以阻止事件的默认行为,可以通过cancelBubble属性来停止事件的进一步传播,由于IE事件流只支持事件冒泡,所以该属性只能停止事件冒泡行为。

W3C事件流

1、W3C事件流支持事件捕获和事件冒泡
2、W3C事件流可以通过可以通过addEventListener()和removeEventListener()来添加和删除事件,这两个方法接受三个参数,依次为 (target,handler,boolean),事件类型,事件处理函数,布尔值(如果设置为false,表示该事件处理函数在事件冒泡阶段触发,如果设置为true,表示该事件处理函数在事件捕获阶段触发,事件冒泡阶段不再触发)需要注意的一点是在使用removeEventListener()方法删除事件时,参数要和创建事件时的参数相同,即第二个参数不支持通过匿名函数来创建,否则会被视为不是同一个方法(同IE事件流规则相同)。
3、W3C事件流中this指向的是目标元素的作用域,不同于IE事件处理程序的作用域为全局作用域,W3C事件流中的事件处理程序的作用域为目标元素所在的作用域,所以this指向的是目标元素。
4、在W3C事件流中,如果为一个元素顺序绑定多个事件,事件执行的顺序是按照顺序执行的。
      const btn = document.getElementById("button");
      btn.attachEvent("onclick",function(){
          console.log("one");
      })

      btn.attachEvent("onclick",function(){
          console.log("two");
      })

       btn.attachEvent("onclick",function(){
          console.log("three");
      })

      //出发事件的运行结果为
      //one
      //two
      //three
5、W3C事件中可以通过preventDefault()方法阻止事件的默认行为,可以通过stopPropagation()方法停止事件在DOM结构中进行传播,即停止事件继续冒泡或者捕获。
6、还可以通过event对象的eventPhase属性来判断事件处于哪一个阶段,调用event.eventPhase,如果返回值为1,则事件处于捕获阶段,如果返回值为2,则事件处于目标阶段,如果返回值为3,则事件处于冒泡阶段。

跨浏览器事件

   var EventUtil = {

        add:function(node,target,handler){
            if(node.addEventListener){
                node.addEventListener(target,handler,false);
            }else if(node.attachEvent){
                node.attachEvent("on"+target,handler);
            }else{
                node["on"+target] = handler;
            }
        },

        remove:function(node,target,handler){
            if(node.removeEventListener){
                node.removeEventListener(target,handler,false);
            }else if(node.detachEvent){
                node.detachEvent("on"+target,handler);
           }else{
               node["on"+target] = handler;
          }
        }
   }

   const btn = document.getElementById("button");
   EventUtil.add(btn,"click",function(){
       console.log("click");
   });

可以通过调用对象EventUtil中的属性来实现添加事件和删除事件,每个属性中通过if-else 来判断浏览器兼容的事件处理程序实现简单的跨浏览器事件调用。

事件委托

事件委托是为处理过多的事件处理程序而设计的,事件委托采用事件冒泡,也就是说,如果想要为一个元素的所有子节点都添加一个事件处理程序的话,只需要获取该父节点的DOM即可,如果想要冒泡到document,也可以直接在document对象上添加事件,而不需要给每一个子节点一个一个添加事件处理程序,以下以W3C事件为例子

         var btn = document.getElementById("button");
         btn.addEventListener("click",function(event){
                  let target = event.target;              
                  switch(target.innerHTML){
                       case  "one":
                           console.log("one");
                           break;
                       case "two":
                           alert("two");
                           break;
                       case:"three":
                           localtion.href = "www.jianshu.com";
                           break;
                       default:
                           alert("undefined");
                            
         },false)

使用事件委托,首先可以减少DOM操作,只需要获取最外层元素的节点即可,其次如果要对每一个元素都一一添加事件,会占用大量的内存,影响整个页面运行的性能,同时通过事件委托也可以提高添加事件的效率,上述实例仅通过switch-case语句就可以实现对于每一个子节点事件的添加,避免了使用一个个addEventListener()或者attachEvent()方法来为每一个子节点添加事件处理程序。

相关文章

  • Javascript中的事件流(IE和W3C的区别)和事件委托

    事件流是用来描述页面接收事件的顺序。目前存在的两种基本的事件流为事件冒泡和事件捕获 事件冒泡 即事件应该从嵌套层次...

  • JavaScript 事件冒泡、事件捕获和事件委托

    JavaScript 事件冒泡、事件捕获和事件委托 以下在chrome、firefox执行通过。 事件流、事件冒泡...

  • JavaScript事件流和事件委托

    作者:codeXiu 来源:掘金 事件流 事件流一共由三个阶段分别是: 1.捕获阶段 2.目标阶段 3.冒泡阶段 ...

  • JavaScript之DOM和IE事件的区别

    JavaScript和HTML之间的交互是通过事件来实现的。事件流描述的是从页面中接收事件的顺序。IE的事件流是事...

  • 7.事件?IE和火狐的事件机制有什么区别?如何阻止冒泡? 事件流描述的是从页面中接受事件的顺序,分为冒泡流和捕获流...

  • JS的原生事件

    javascript原生的事件包括事件流、处理函数、事件对象等。而在兼容性也有问题。 1事件流 事件流是ie和Ne...

  • 【事件】事件流

    1、JavaScript和HTML之间的交互通过事件实现的。2、事件流描述的是从页面中接收事件的顺序。3、IE 和...

  • 事件流的3个阶段:捕获、冒泡、目标

    事件模型:IE事件模型和DOM标准事件模型区别:IE事件模型没有捕获阶段,只有冒泡。 事件流的三个阶段:先捕获阶段...

  • js事件深入学习

    JavaScript的事件机制包含,事件绑定、事件监听、事件委托(事件代理)等 js中的事件流 ① .冒泡:当下级...

  • Unity3d-c#-观察者设计模式-猫抓老鼠

    在这个例子中运用了委托事件机制讲述了事件和委托的区别最大的区别是:事件是特殊的受限的委托,事件只能在类内部调用,不...

网友评论

      本文标题:Javascript中的事件流(IE和W3C的区别)和事件委托

      本文链接:https://www.haomeiwen.com/subject/rputuqtx.html