事件的捕获和冒泡

614 阅读2分钟

事件捕获和事件冒泡


盒子多层嵌套时,当你点击,浏览器实际上并不知道点的是哪个,它的一层层去查,查到有点击事件则执行。

历史初期查找方案: ie是从最内层开始查,直到查到最外层,即为冒泡流; 而网景提出的是从最外层开始查,即为捕获流;

现阶段方案: W3C提出了都支持方案,但ie低版本只支持冒泡流,为了兼容建议使用冒泡流。

事件绑定的方式


  1. dom里直接配置属性
<div onclick="show()">按钮</div>

考虑,js和html的分离不建议使用此方式

  1. js操作dom属性绑定
document.getElementById('btn').onclick = function(e){
    ...
}
  1. 事件监听

非ie8-

绑定:target.addEventListener(type, fn, true/false)

移除:target.removeEventListener(type, fn, true/false)

type指事件类型;fn指执行函数;设为true指使用捕获流(实际上目前第3个参数可以是个对象,后期有需要再补充)

区别:除了可以设置捕获,事件监听还可以绑定多个事件,而使用属性绑定只能有一个。

document.getElementById('e').addEventListener('click',function (event) {
	console.log('e',event)
},true);

ie8-

绑定:target.attachEvent(type, fn)

移除:target.detachEvent(type, fn)

ie是冒泡流,需要注意的是fn里的this指向window(正常指向触发事件的元素,这很有用)

注:各种浏览器默认的都是冒泡,避免使用捕获

event 对象


使用注意:var e= event || window.event (火狐使用window.event会报错)。

表示在DOM中发生的任何事件,在事件处理函数被传入,主要关注2个属性:currentTarget target

  1. event.currentTarget / this 当前目标元素(绑定事件的元素)

  2. event.target / event.srcElement(ie8-) 触发目标元素(从哪个元素开始触发的,冒泡是最内层的盒子,捕获则相反)

//加上div#f内套div#e
document.getElementById('e').addEventListener('click',function (e) {
	console.log(e.target); //div#f
	console.log(e.currentTarget); //div#e
},true);

注:有时可能只希望触发一个事件或者事件委托,可以使用此方式

阻止默认事件

比如用在阻止radio/checkbox选中

  1. 对于onclick绑定方式:return false
  2. 对于监听绑定方式:
  • event.preventDefault()
  • window.event.returnValue = false (ie8-)

事件委托


即把事件绑定在父节点上,通常用在子节点不存在时的情况,或者子节点多且绑定相同事件的情况

//如下,div#f不存在的情况下绑定好事件
document.getElementById('e').addEventListener('click',function (e) {
	var e=e||window.event;
	var target=e.target||e.srcElement;
	if(target.id==='f'){
		alert('find children f')
	}
});
document.getElementById('e').innerHTML='<div id="f"></div>';