浏览器事件的过程
浏览器事件模型中的过程主要分为三个阶段:捕获阶段、目标阶段、冒泡阶段。具体可以看图:
第三个参数
注意addEventListener
的第三个参数, 如果为true
,就是代表在捕获阶段执行。如果为false
,就是在冒泡阶段进行空口这么说可能不好理解,咱们来看一下代码。
1 |
|
1 |
|
1 |
|
阻止事件的传播
e.stopPropagation
e.stopPropagation
大家经常听到的可能是阻止冒泡,实际上这个方法不只能阻止冒泡,还能阻止捕获阶段的传播。我们在parent
中加入stopPropagation
,看下代码:
1 |
|
1 |
|
我们可以看到,stopPropagation
阻止了捕获
事件的传播,并且也阻止了冒泡
事件的传播。但是大家思考下,要是在parent
上再次绑定一个捕获事件,stopPropagation
能不能阻止呢?我们改写下代码:
1 |
|
我们可以看到,parent
上绑定的另一个捕获事件并没有被阻止掉,那么如果有这样的需求该怎么办呢?那就要用到stopImmediatePropagation
e.stopImmediatePropagation
如果有多个相同类型事件的事件监听函数绑定到同一个元素,当该类型的事件触发时,它们会按照被添加的顺序执行。如果其中某个监听函数执行了stopImmediatePropagation
方法,则当前元素剩下的监听函数将不会被执行。
我们把代码改写下:
1 |
|
我们可以看到,parent
同级的捕获2
成功被阻止了,但是捕获0
没有被阻止掉,原因是事件的执行是按照顺序执行的,从0
->1
->2
。
阻止默认行为 e.preventDefault
preventDefault
可以阻止事件的默认行为发生,默认行为是指:点击a
标签就转跳到其他页面、拖拽一个图片到浏览器会自动打开、点击表单的提交按钮会提交表单等等,因为有的时候我们并不希望发生这些事情,所以需要阻止默认行为。我们给html
中的a
标签加上事件,并阻止默认行为,同时删除parent的阻止事件传播
。
1 |
|
我们可以看到,点击a
标签之后没有发生跳转,a
标签的默认事件成功被阻止了。
兼容性
attachEvent
——兼容:IE7、IE8; 不支持第三个参数来控制在哪个阶段发生,默认是绑定在冒泡阶段
addEventListener
——兼容:firefox、chrome、IE、safari、opera
事件委托
我们来手打一个事件委托,给出一个ul+li
,输出点击的li
的内容和索引:
1 |
|
先来一个在li
上绑定事件:
1 |
|
再来一个在ul
上绑定事件:
1 |
|
封装⼀个多浏览器兼容的绑定事件函数
1 |
|