目录
addEventListener
取消绑定事件
removeEventListener
事件捕获&冒泡
事件冒泡
事件捕获
事件捕获和事件冒泡同时存在
1.捕获在前
2.冒泡在前
注意
取消事件冒泡
addEventListener
在复杂的项目开发中,javascript和html的解耦变得至关重要,我们被推荐使用事件动态绑定的方式来处理按钮的事件。W3C为我们提供了addEventListener()函数用来为指定的dom元素动态绑定事件。这个函数有三个参数:
type:用来设置时间类型,例如click
listener:用来设置监听事件的函数,及type类型的事件发生后执行的函数
大部分情况下,确切的说是我们绑定事件的元素的父元素和子元素都不存在操作类型相同的触发事件时,前两个参数就可以满足我们为按钮绑定事件的需求。
比如:
function sayHello() {console.log("hello");}var myDiv = document.getElementById("myDiv");myDiv.addEventListener("click", sayHello);
这样我们点击id为myDiv的元素时,控制台就会输出"Hello"。
通过上面代码可以看到对于addEventListener方法的第一个参数,可以是:click,mouseover,mouseout诸如此类的。于是改写addEventListener方法如下:
function addEvent(elem,type,handle){if(elem.addEventListener){elem.addEventListener(type,handle,false);}else if(elem.attachEvent){elem.attachEvent('on'+type,function(){handle.call(elem);})}else{elem['on' + type] = handle;}}
取消绑定事件
removeEventListener
var div = document.getElementsByTagName('div')[0];div.onclick = function(){console.log('处理事件');this.onclick = null;//点击一次之后失效}div.removeEventListener('click',test,false);
对于removeEventListener方法:element.removeEventListener(event,function,useCapture)
function不能使用匿名函数!!!
事件捕获&冒泡
在javascript里,事件委托是很重要的一个东西,事件委托依靠的就是事件冒泡和捕获的机制。DOM(文档对象模型)结构是一个树型结构,当一个HTML元素产生一个事件时,该事件会在元素节点与根结点之间的路径传播,路径所经过的结点都会收到该事件,这个传播过程可称为DOM事件流。
事件冒泡
<!DOCTYPE html><html><head><meta charset="UTF-8"><title></title><style type="text/css">.wrapper{width: 300px;height: 300px;background-color: aqua;}.content{/*margin-left: 300px;*/width: 200px;height: 200px;background-color: slateblue;}.box{/*margin-left: 200px;*/width: 100px;height: 100px;background-color: aquamarine;}</style></head><body><div class="wrapper"><div class="content"><div class="box"></div></div></div><script type = "text/javascript">var wrapper = document.getElementsByClassName('wrapper')[0];var content = document.getElementsByClassName('content')[0];var box = document.getElementsByClassName('box')[0];wrapper.addEventListener('click',function(){console.log('wrapper')},false);content.addEventListener('click',function(){console.log('content')},false);box.addEventListener('click',function(){console.log('box')},false);</script></body></html>
事件从目标节点自上而下向Document节点传播的阶段。在浏览器中运行点击最外层div:wrapper,
运行结果显示:box content wrapper(从内向外传递)
事件捕获
<!DOCTYPE html><html><head><meta charset="UTF-8"><title></title><style type="text/css">.wrapper{width: 300px;height: 300px;background-color: aqua;}.content{/*margin-left: 300px;*/width: 200px;height: 200px;background-color: slateblue;}.box{/*margin-left: 200px;*/width: 100px;height: 100px;background-color: aquamarine;}</style></head><body><div class="wrapper"><div class="content"><div class="box"></div></div></div><script type = "text/javascript">var wrapper = document.getElementsByClassName('wrapper')[0];var content = document.getElementsByClassName('content')[0];var box = document.getElementsByClassName('box')[0];wrapper.addEventListener('click',function(){console.log('wrapper')},true);content.addEventListener('click',function(){console.log('content')},true);box.addEventListener('click',function(){console.log('box')},true);</script></body></html>
事件从Document节点自上而下向目标节点传播的阶段。点击最外层div:
运行结果:从外向内进行输出 wrapper content box。
事件捕获和事件冒泡同时存在
1.捕获在前
<!DOCTYPE html><html><head><meta charset="UTF-8"><title></title><style type="text/css">.wrapper{width: 300px;height: 300px;background-color: aqua;}.content{/*margin-left: 300px;*/width: 200px;height: 200px;background-color: slateblue;}.box{/*margin-left: 200px;*/width: 100px;height: 100px;background-color: aquamarine;}</style></head><body><div class="wrapper"><div class="content"><div class="box"></div></div></div><script type = "text/javascript">var wrapper = document.getElementsByClassName('wrapper')[0];var content = document.getElementsByClassName('content')[0];var box = document.getElementsByClassName('box')[0];wrapper.addEventListener('click',function(){console.log('wrapperBuhuo')},true);content.addEventListener('click',function(){console.log('contentBuhuo')},true);box.addEventListener('click',function(){console.log('boxBuhuo')},true);wrapper.addEventListener('click',function(){console.log('wrapperMaopao')},false);content.addEventListener('click',function(){console.log('contentMaopao')},false);box.addEventListener('click',function(){console.log('boxMaopao')},false);</script></body></html>
2.冒泡在前
<!DOCTYPE html><html><head><meta charset="UTF-8"><title></title><style type="text/css">.wrapper{width: 300px;height: 300px;background-color: aqua;}.content{/*margin-left: 300px;*/width: 200px;height: 200px;background-color: slateblue;}.box{/*margin-left: 200px;*/width: 100px;height: 100px;background-color: aquamarine;}</style></head><body><div class="wrapper"><div class="content"><div class="box"></div></div></div><script type = "text/javascript">var wrapper = document.getElementsByClassName('wrapper')[0];var content = document.getElementsByClassName('content')[0];var box = document.getElementsByClassName('box')[0];wrapper.addEventListener('click',function(){console.log('wrapperMaopao')},false);content.addEventListener('click',function(){console.log('contentMaopao')},false);box.addEventListener('click',function(){console.log('boxMaopao')},false);wrapper.addEventListener('click',function(){console.log('wrapperBuhuo')},true);content.addEventListener('click',function(){console.log('contentBuhuo')},true);box.addEventListener('click',function(){console.log('boxBuhuo')},true);</script></body></html>
事件捕获和事件冒泡同时存在,先捕获再冒泡
但是在第二种的运行结果中可以看到,在捕获事件发生的时候第三次输出的是冒泡并不是捕获。
注意
当冒泡与捕获同时存在时,对于执行事件 谁在前面谁先执行:
在代码中boxMaopao在前面先执行,首先捕获到box,box执行
box.addEventListener('click',function(){console.log('boxMaopao')},false);
输出‘boxMaopao'。再执行:
box.addEventListener('click',function(){console.log('boxBuhuo')},true);
所以对于第二种的输出结果就毋庸置疑了。
取消事件冒泡
function stopBubble(event){if(event.stopPropagation()){event.stopPropagation();}else{event.cancelBubble = true;}}