js事件机制
一、js事件机制三个阶段:事件捕获、事件目标处理函数、事件冒泡
js中事件执行的整个过程称之为事件流,分为三个阶段:事件捕获阶段,事件目标处理函数、事件冒泡。
当某个元素触发某个事件(如:click),顶级对象document发出一个事件流,顺着dom的树节点向触发它的目标节点流去,直到达到目标元素,这个层层递进,向下找目标的过程为事件的捕获阶段,此过程与事件相应的函数是不会触发的。
到达目标函数,便会执行绑定在此元素上的,与事件相应的函数,即事件目标处理函数阶段。
最后,从目标元素起,再依次往顶层元素对象传递,途中如果有节点绑定了同名事件,这些事件所对应的函数,在此过程中便称之为事件冒泡。
通常情况下,事件相应的函数是在冒泡阶段执行的。addEventListener的第三个参数默认为false,表示冒泡阶段执行(为true的时候,表示捕获阶段执行)。
使用e.stopPropgation()或e.cancelBubble = true(IE)可以阻断事件向当前元素的父元素冒泡。

以上是在冒泡阶段触发事件,但是由于最内层的元素阻止了默认事件,所以导致冒泡事件无法产生。




前三个结果是事件捕获阶段执行函数输出的结果,是从最高节点开始,但凡绑定了clik事件,便会执行;之后进入冒泡阶段,由于div[1]身阻止了事件冒泡,因此它的父级div[0]的click事件是不会触发的,事件到div[1]便结束了。
如果把阻止冒泡的行为添加在捕获阶段,如捕获阶段的div[1]身上,则只会依次输出捕获过程中触发click事件时div[0]、div[1]的函数执行结果,之后的捕获行为和冒泡行为将全部被阻断。


二、实际应用
1、处理事件冒泡(stopPropagation),阻止默认事件(preventDefault)工具类,兼容IE

2、DOM0级与DOM2级的区别
定义:
(1)DOM 0级
IE和主流浏览器都支持的一种写法,是在事件的冒泡阶段执行的,可以在注册函数内直接使用this来引用注册事件的元素。
添加方式--直接js或者HTML挂载法
一是在标签内写onclick
二是在JS写onclick=function(){} 函数

移除方式
移除事件的方法是把事件设置为null 即element.onClick = null
(2)DOM2级
IE模式下多个事件的监听与移除方法
IE浏览器中HTML元素有个attachEvent方法允许外界注册该元素多个事件监听器,例如:element.attachEvent('onclick',observer)
atachEvent接受两个参数,第一个参数是事件名称,第二个参数observer是回调处理函数,这里值得说明一下,有个会经常出错的地方,IE利用attachEvent注册的处理函数调用时this指向不再是先前注册事件元素,这时候的this是window对象。
要移除先前注册的事件的监听器,调用element的detachEvent方法即可。参数相同。element.detachEvent('onclick',observer)
标准的浏览器下注册多个事件监听器与移除事件监听器的方法
实现标准的浏览器与IE浏览器中注册元素事件监听器方式有所不同,它通过元素的addEventListener方法注册,该方法即支持注册冒泡型事件处理,又支持捕获型事件处理element.addEvenListener('click',observer,useCapture)
addEventListener方法接受三个参数,第一个参数是事件名称,值得注意的是,这里事件名称与IE不同,事件名称是没有‘on’开头的;第二个参数obsever是回调处理函数;第三个参数注明该处理函数是在事件传递过程中的捕获阶段调用还是冒泡阶段调用,true则表示在捕获阶段调用,为false表示在冒泡阶段调用
移除已注册的事件监听器用element的removeEventListener即可,参数不变element.removeEventListener('click',observer,useCapture);

区别:
如果定义了两个DOM0级事件,DOM0级事件会覆盖,DOM2级事件不会被覆盖,会依次执行,DOM0级和DOM2可以共存,不相互覆盖,但是DOM0级之间依然会覆盖。