以前对事件只会用jq的bind绑定一下,脑海里留着书中的事件循环,一直认为事件就是这儿循环的,最近看园子里的文章,对事件的了解更模糊了
所以我做了个小实验,总结一下看的这些零零碎碎的文章,如果总结错了,请在评论里指出
首先,在页面上方4个div标签,一个嵌套个用来测试捕获和冒泡,
因为捕获和冒泡的重点是过程,而不是起点和重点,所以我只在中间的两个div small和meddiv 上绑定了事件
基本的html代码如下
1
2
3
4
5
6
7
8
9
10
11
12
13 |
<div id= "bigdiv"
style= "width: 800px; height: 800px;background-color: gold;float: left;margin: 10px 10px 10px 10px" > <span id= "bigdiv_e" >bigdiv</span> <div id= "Meddiv"
style= "width: 500px; height: 500px;background-color: #0000ff;float: left;margin: 10px 10px 10px 10px" > <span id= "Meddiv_e" >Meddiv</span> <div id= "small"
style= "width: 300px; height: 300px;background-color: silver;float: left;margin: 10px 10px 10px 10px" > <span id= "small_e" >small</span> <div id= "verysmall"
style= "width: 100px; height: 100px;background-color: saddlebrown;float: left;margin: 10px 10px 10px 10px" > <span id= "verysmall_e" >verysmall</span> </div> </div> </div> </div> |
1 |
基本的js如下 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 |
<script> function
geteventPhasetype(num){ var
state= "未知" if (num==1) { state= "捕获阶段" ; } else
if (num==2) { state= "正常事件派发" ; } else
if (num==3) { state= "起泡阶段" ; } return
state+ "eventPhase 为" +num; } var
Meddiv=document.getElementById( "Meddiv" ); Meddiv.addEventListener( ‘click‘ , function (e){ console.log( "Meddiv 捕获注册的:target:" + e.target.id+ ",阶段" +geteventPhasetype( e.eventPhase)+ ",currentTarget:" + e.currentTarget.id); }, true ); Meddiv.addEventListener( ‘click‘ , function (e){ console.log( "Meddiv 冒泡注册的:target:" + e.target.id+ ",阶段" + geteventPhasetype( e.eventPhase)+ ",currentTarget:" + e.currentTarget.id); }, false ); var
small=document.getElementById( "small" ); small.addEventListener( ‘click‘ , function (e){ console.log( "small 捕获注册的:target:" + e.target.id+ ",阶段" +geteventPhasetype( e.eventPhase)+ ",currentTarget:" + e.currentTarget.id); }, true ); small.addEventListener( ‘click‘ , function (e){ console.log( "small 冒泡注册的:target:" + e.target.id+ ",阶段" +geteventPhasetype( e.eventPhase)+ ",currentTarget:" + e.currentTarget.id); }, false ); </script> |
这些js分别完成了针对冒泡阶段和捕获阶段的事件监听,geteventPhasetype 根据事件的eventPhase
判断当前处理事件在状态
第一个实验,在黄色区域点击,
实验结果:console
没有任何输出,Meddiv,small没有输出,
第二个实验,在蓝色区域点击,
实验输出:Meddiv
捕获注册的:target:Meddiv,阶段正常事件派发eventPhase 为2,currentTarget:Meddiv
Meddiv
冒泡注册的:target:Meddiv,阶段正常事件派发eventPhase 为2,currentTarget:Meddiv
实验结果:1
里面的div没有捕获到事件
2
点击Meddiv时候,Meddiv事件的状态始终为eventPhase=2,事件处理阶段,捕获和冒泡注册的时间的事件都会执行
第三个实验:点击银色区域,
实验输出:Meddiv
捕获注册的:target:small,阶段捕获阶段eventPhase 为1,currentTarget:Meddiv
small
捕获注册的:target:small,阶段正常事件派发eventPhase 为2,currentTarget:small
mall
冒泡注册的:target:small,阶段正常事件派发eventPhase 为2,currentTarget:small
Meddiv
冒泡注册的:target:small,阶段起泡阶段eventPhase 为3,currentTarget:Meddiv
实验结果:点击 银色区域small
的时候,外面包裹的Meddiv,处于捕获阶段,执行捕获节点的方法
small
处于事件正常派发阶段,处理捕获和冒泡的执行的方法
外面包裹的Meddiv,处于冒泡阶段,执行冒泡的执行方法
另外
在处于正常派发阶段的时候,执行方法的顺序和注册顺序有关,例如颠倒了注册方法的顺序,执行结果如下
Meddiv 捕获注册的:target:small,阶段捕获阶段eventPhase
为1,currentTarget:Meddiv
mall 冒泡注册的:target:small,阶段正常事件派发eventPhase
为2,currentTarget:small
small 捕获注册的:target:small,阶段正常事件派发eventPhase
为2,currentTarget:small
Meddiv 冒泡注册的:target:small,阶段起泡阶段eventPhase
为3,currentTarget:Meddiv
第四个实验:点击最里面的紫色区域
实验输出:Meddiv
捕获注册的:target:verysmall,阶段捕获阶段eventPhase 为1,currentTarget:Meddiv
small
捕获注册的:target:verysmall,阶段捕获阶段eventPhase 为1,currentTarget:small
small
冒泡注册的:target:verysmall,阶段起泡阶段eventPhase 为3,currentTarget:small
Meddiv
冒泡注册的:target:verysmall,阶段起泡阶段eventPhase 为3,currentTarget:Meddiv
实验结果:Meddiv
和small先执行捕获对应的方法,然后执行冒泡对应的方法
实验猜想:事件捕获和事件冒泡那个性能高,那个最高效
事件捕获为从外向内,到达点击的元素后,就停止向下传播
事件冒泡为,事件在到达点击元素后,处理完事件,如果不阻止事件传播,事件就会向上冒泡,一直到最顶部
so
网页布局改如何布局,移动端争分夺秒的加载和寸土必争的内存改如何处理,答案是网页扁平化
要这样的结构布局
1 |
|
1 |
不要这样的结构布局<br><br> |
1 |
|
1 |
减少事件传播管卡,加速系统响应 |
1 |
以前很少在事件对应的方法执行时判断事件所处的状态,通过这次试验发现,如果使用原生的方法添加事件, |
1 |
根据 eventPhase、 currentTarget、target组合判断是否应该执行方法,很重要的 |
dom事件不求甚解,色解事件捕获和冒泡,布布扣,bubuko.com
原文:http://www.cnblogs.com/qqloving/p/3576908.html