事件流模型
事件机制包括三个阶段:
1、捕获
2、目标触发
3、冒泡
DOM结构是树形结构,当页面中的某个元素触发了某个事件,事件会从最顶层的window对象开始,向下传播到目标元素,即‘捕获阶段’,然后目标元素触发相应的事件,即‘目标触发’,再向上传播到window,途径的祖先元素都会触发相应的事件,即‘冒泡’。
有如下文档:

显示结果如图:

一、此时添加如下代码:

点击蓝色d3区域则:
依次弹出d3,d2,d1。
根据事件机制,点击d3后,首先从window开始向下传播到目标元素d3,触发d3的click事件,弹出'd1',然后向上传播,沿途经过祖先元素d2,d2也绑定了点击事件,因此触发其点击事件,弹出'd2',继续向上传播,到d3,d3同样绑定了点击事件,触发而弹出'd3'。继续向上传播到window对象,不再有click事件。
若要阻止事件冒泡,可以使用e.stopPropagation()

e.stopPropagation()可阻止事件冒泡。此时点击d3则只会触发目标元素的事件,不会冒泡,即只弹出‘d3’。
二、若用addEventListener为元素添加事件:
addEventListener(event,fn,useCapture)
其中第3个参数useCapture是一个Boolean值,可以用来设置事件是在捕获阶段执行,还是冒泡阶段执行。默认值为false,即冒泡阶段执行。
添加如下代码:

则会依次弹出‘d3’,‘d2’,‘d1’。
此时若修改d1的useCapture为true,则d1绑定的click在事件捕获阶段就会执行,即依次弹出‘d1’,‘d3’,‘d2’。
补充:
1)IE不支持addEventListener,而是用attachEvent(event,fn)方法,由于IE的事件模型默认是在冒泡阶段执行,所以此方法没有第三个参数来设置事件的执行时机。IE用event.cancelBubble=true来阻止冒泡。
另外:

与addEventListener不同的是:此时this指向window,而在addEventListener中,是指元素p本身。
2)e.preventDefaut()用来阻止默认事件,如a元素的href链接,但不能阻止冒泡。e.stopPropagation()用来阻止冒泡。
3)事件委托就是利用了事件冒泡的原理。把要执行相同事件的子元素的事件委托给父元素,只用在父元素绑定一个事件就可以,在冒泡阶段执行。此时可以用e.target获取目标元素,即点击了哪个元素。如下:

点击第二个li时:

e.target是直接触发事件的元素,this和e.currentTarget是调用这个事件的元素,是一样的。
浙公网安备 33010602011771号