如果要把HTML元素的事件与某个函数绑定起来,可以有下面三种方法,以最常见的“点击”事件为例。
方法一:
直接在对应的HTML元素标签上绑定函数
1
|
< button id = 'submit' onclick = 'onClickFn()' >Click Me!</ button > |
方法二:
在JavaScript代码里面指定元素的“onclick”方法
1
2
3
|
var btn = document.getElementById( 'submit' ); btn.onclick = onClickFn; |
方法三:
使用事件监听绑定方法
1
2
3
|
var btn = document.getElementById( 'submit' ); btn.addEventListener( 'click' , onClickFn, false ); |
三种方法都可以在button被点击的时候调用onClickFn函数,但是有所区别。
第一种方法不推荐,因为违反了HTML与JavaScript分离的准则;
第二种方法只能给一个事件绑定一个响应函数,重复绑定会覆盖之前的绑定;
第三种方法比较推荐,可以绑定多个不同的函数。
不过退步推荐不是重点,重点是第三种方法中的第三个参数为何是“false”?
当鼠标点击所看到的的按钮时,其实发生了一系列的事件传递,可以想象一下,button实际上是被body“包裹”起来的,body是被html“包裹”起来的,html是被document“包裹”起来的,document是被window“包裹”起来的。所以,在你的鼠标点下去的时候,最先获得这个点击的是最外面的window,然后经过一系列传递才会传到最后的目标button,当传到button的时候,这个事件又会像水底的泡泡一样慢慢往外层穿出,直到window结束。
综上,一个事件的传递过程包含三个阶段,分别称为:
捕获阶段,目标阶段,冒泡阶段
目标指的就是包裹得最深的那个元素。
假设HTML有如下元素:
1
2
3
4
5
|
< div id = 'd' > < p id = 'p' > < span id = 's' >Click Me!</ span > </ p > </ div > |
JavaScript代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
|
var div = document.getElementById( 'd' ); var p = document.getElementById( 'p' ); var span = document.getElementById( 's' ); function onClickFn (event) { var tagName = event.currentTarget.tagName; var phase = event.eventPhase; console.log(tagName, phase); } div.addEventListener( 'click' , onClickFn, false ); p.addEventListener( 'click' , onClickFn, false ); |
此时,点击“Click Me!”,即可在控制台看到如下结果:
1
2
|
P 3 DIV 3 |
其中“3”和“冒泡阶段”对应。
可以看出,p和div都是在冒泡阶段相应了事件,由于冒泡的特性,裹在里层的p率先做出响应。
如果把上面代码里面中addEventListener的第三个参数设置为true,那么运行的结果如下:
1
2
|
DIV 1 P 1 |
由此,addEventListener的第三个参数设置为true和false的区别已经非常清晰了:
true表示该元素在事件的“捕获阶段”(由外往内传递时)响应事件;
false表示该元素在事件的“冒泡阶段”(由内向外传递时)响应时间。
至此,你可能会有疑问,还有一个“目标阶段”呢?
您不妨给span元素绑定事件,自己测试一下。
在冒泡阶段,如果不希望事件继续往上传播,例如,冒泡的p的时候就停止传播,那么,可以在p的事件回调函数里面这么写:
1
2
3
4
|
function onClickFn (event) { // code here event.stopPropagation(); } |
这样,冒泡到p的时候,就不会再向上传播了,即,div不会收到冒泡上来的click事件。
如果还想把其它与p绑定的响应函数的事件也“屏蔽”掉,需要把stopPropagation换为stopImmediatePropagation。
来源:
http://my.oschina.net/u/1454562/blog/205010
可参考:
http://www.neoease.com/stoppropagation-and-preventdefault-and-return-false/