问题描述
最近做一个项目,要给一个页面在顶部新增一个入口,本以为是个超级简单的事情,结果发现用a标签把点击元素包裹起来无效,给点击元素绑定事件也无效,一件本以为简单的事情,结果出了稀奇古怪的效果。
问题排查
一般而言是不会有这个原因的,为什么给元素加了事件,点击却不触发?是事件没绑定成功?在chrome里面的event listener里面检查,发现有点击事件。那么就是事件没绑定了却没触发。测试了一下,发现点击在子元素才不会触发事件。我们都知道子元素是会继承父元素的事件的。搜索了一下,终于找到鬼魁祸首 一个子元素的事件绑定中有 return false。
两种事件流
根据事件的传播顺序不同,分为两种事件流。
冒泡型事件流:从子节点向根节点传播。
捕获型事件流:从父节点到子节点。
现在我们使用的事件绝大多数都是冒泡型的,所有的现代浏览器都支持冒泡,一些老浏览器不支持捕获。
阻止事件继承
1.为子元素添加和父元素一样的事件,然后在子元素中阻止事件冒泡。eg:
$("#child").on('click',function(e){
e.cancelBubble = true;//ie
e.stopPropagation(); //阻止事件冒泡
});
- 对于onmouseover 和mouseout 不能用上述方法来阻止事件冒泡,这个时候可以用 return false。eg:
function overOrOut(e,target){
if(e.type != "mouseover" && e.type != "mouseout"){
return false;
}
//do otherthing
}
return false也能阻止事件冒泡,但是它不仅阻止了事件冒泡也阻止了事件本身,相当于阻塞了该事件,不再执行。而e.stopPropagation()只是阻止事件冒泡。
tips:链接等是有默认事件的,阻止事件冒泡前需要先阻止事件的默认事件 event.preventDefault或window.event.returnValue=false。