js里事件传播流程

  Javascript与HTML之间的交互是通过事件实现的。  

  事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间。 

  可以使用侦听器来预定事件,以便事件发生时执行相应代码

 

事件流

  JS事件流最早要从IE和网景公司的浏览器大战说起,IE提出的是冒泡流,而网景提出的是捕获流,后来在W3C组织的统一之下,JS支持了冒泡流和捕获

流,但是目前低版本的IE浏览器还是只能支持冒泡流(IE6,IE7,IE8均只支持冒泡流),所以为了能够兼容更多的浏览器,建议大家使用冒泡流。

事件流原理图如下:

 

从图中我们可以知道

1、一个完整的JS事件流是从window开始,最后回到window的一个过程

2、事件流被分为三个阶段(1~5)捕获过程、(5~6)目标过程、(6~10)冒泡过程

3、在冒泡过程中6比7早触发。

下面举个例子说明js中的事件

<body>
  <div class="parent">
    parent
    <div class="child">child</div>
  </div>
</body>
  <script type="text/javascript">
    var oParent=document.getElementsByClassName("parent")[0];
    var oChild=document.getElementsByClassName("child")[0];
    oParent.oclick=function(){
      console.log("parent");
    }
    oParent.onclick=function(){
      console.log("parent-2");
    }
    oChild.onclick=function(){
      console.log("chlid");
    }
  </script>

点击child运行结果是:

  上面的例子是Dom0级事件,在Dom0级事件中一个元素相同的事件只能绑定一次如(onclick),并且绑定的是最后绑定的那个事件,这个有点像jquery

的html方法一样,后面的会覆盖掉前面的内容一样。在Dom0级事件里只有事件冒泡没有事件捕获。

在Dom2级事件里支持事件冒泡和事件捕获

 oParent.addEventListener("click",function(){
      console.log("parent");
    },false);
    oParent.addEventListener("click",function(){
      console.log("parent-2");
    },false);
    oChild.addEventListener("click",function(){
      console.log("chlid");
    },false);

执行结果:

 

  这里是发生了事件冒泡,点击child,先执行了child后输出了parent和parent-2,同时可以看出Dom2级事件是支持添加同名事件的按照先后顺序执

行。addEventListener是Dom2里添加事件监听的写法可以接受三个参数,第一个参数是事件名称,第二个是事件处理函数,第三个参数是布尔值true是

设置事件捕获,false是设置事件冒泡,默认情况下是false。IE里面添加监听事件是attachEvent但是IE不支持事件捕获,所以attachEvent只有前两

个参数,不能设置true和false,同时事件名也要加上on。比如addEventListener的单击事件是click,而attachEvent的单击事件是onclick。有添

加监听事件就有移除监听事件,与addEventListener相对的是removeEventListener,与attachEvent相对应的是deatchEvent这两个写法与上面

类似,需要注意的是移除事件时要同时删除事件名和对应的方法。

注意:removeEventListener() 不能移除匿名函数,定义的函数是可以的。removeEventListener需要知道你需要移除的是哪个事件处理函数。

匿名函数丢弃了自身函数名,所以移除不了。

为了解决和IE的兼容问题会将两种写法封装成一个函数进行调用,因为IE不支持事件捕获,所以尽量使用事件冒泡以解决兼容问题。

下面是封装的函数示例可以参考一下

var EventUtil = {
    addHandler: function (element, type, handler) {
        if (element.addEventListener) {
            element.addEventListener(type, handler, false);
        } else if (element.attachEvent) {
            element.attachEvent("on" + type, handler);
        } else {
            element["on" + type] = handler;
        }
    },
    removeHandler: function (element, type, handler) {
        if (element.removeEventListener()) {
            element.removeEventListener(type, handler, false);
        } else if (element.detachEvent) {
            element.detachEvent("on" + type, handler);
        } else {
            element["on" + type] = null;
        }
    }
};

  这两个方法首先都会检测传入的元素中是否存在DOM2级方法。如果存在DOM2级方法,则使用该方法;如果存在的是IE的方法,则采取第二种方案。最后

一种可能就是DOM0级方法,此时使用的是方括号语法来将属性名指定为事件处理程序,或者将属性设置为null。

posted @ 2019-03-07 21:45  王辉冯  阅读(2572)  评论(0编辑  收藏  举报