事件冒泡和事件捕获分别由微软和网景公司提出,这两个概念都是为了解决页面中事件流(事件发生顺序)的问题。javascript
以下:假设三层div都有事件监听,这时咱们点击的小的蓝方框,事件执行的顺序是怎么样的呢html
<div id="s1" style="height: 400px;width: 400px;border: 1px solid red">红 <div id="s2" style="height: 200px;width: 200px;border: 1px solid yellow"> 黄 <div id="s3" style="height: 100px;width: 100px;border: 1px solid blue">蓝</div> </div> </div>
微软提出了名为事件冒泡(event bubbling)的事件流。事件冒泡能够形象地比喻为把一颗石头投入水中,泡泡会一直从水底冒出水面。也就是说,事件会从最内层的元素开始发生,一直向上传播,直到document对象。
所以在事件冒泡的概念下在div元素上发生click事件的顺序应该是div -> body -> html -> document
java
网景提出另外一种事件流名为事件捕获(event capturing)。与事件冒泡相反,事件会从最外层开始发生,直到最具体的元素。
所以在事件捕获的概念下在div元素上发生click事件的顺序应该是document -> html -> body -> div -> div
浏览器
addEventListener第三个参数默认值是false,表示在事件冒泡阶段调用事件处理函数;若是参数为true,则表示在事件捕获阶段调用处理函数。函数
s1 = document.getElementById('s1') s2 = document.getElementById('s2') s3 = document.getElementById('s3') s1.addEventListener("click",function(e){ console.log("红 冒泡事件");//从底层往上 },false);//第三个参数默认值是false,表示在事件冒泡阶段调用事件处理函数;若是参数为true,则表示在事件捕获阶段调用处理函数。 s2.addEventListener("click",function(e){ console.log("黄 冒泡事件"); },false); s3.addEventListener("click",function(e){ console.log("蓝 冒泡事件"); },false);
s1.addEventListener("click",function(e){ console.log("红 捕获事件"); },true); s2.addEventListener("click",function(e){ console.log("黄 捕获事件"); },true); s3.addEventListener("click",function(e){ console.log("蓝 捕获事件"); },true);
s1.addEventListener("click",function(e){ console.log("红 冒泡事件"); },false); s2.addEventListener("click",function(e){ console.log("黄 冒泡事件"); },false); s3.addEventListener("click",function(e){ console.log("蓝 冒泡事件"); },false); s1.addEventListener("click",function(e){ console.log("红 捕获事件"); },true); s2.addEventListener("click",function(e){ console.log("黄 捕获事件"); },true); s3.addEventListener("click",function(e){ console.log("蓝 捕获事件"); },true);
好比我想点击ul标签里面的li获取它的值,有点人就会遍历去给每一个li加一个事件监听
其实咱们能够在li的父级加一个事件监听,这就至关于把事件监听委托给了ul
咱们点击li的时候是会打出值的测试
<ul id="ul"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> </ul>
ul = document.getElementById('ur') ul.addEventListener("click",function(e){ console.log(e.target.innerText); },false);
onclick不能像addEventListener那样指定是事件类型,它只能是事件冒泡spa
s1.onclick=function(){ console.log('红') } s2.onclick=function(){ console.log('黄') } s3.onclick=function(){ console.log('蓝') return true }
但某一些时候咱们不想触发事件冒泡怎么办或者是不想触发默认的一些方法代理
这是W3C的标准方法,stopPropagation是事件对象(Event)的一个方法,做用是阻止目标元素的冒泡事件,可是会不阻止默认行为。
IE使用的是IE则是使用e.cancelBubble = truecode
function stopBubble(e) { //若是提供了事件对象,则这是一个非IE浏览器 if ( e && e.stopPropagation ) //所以它支持W3C的stopPropagation()方法 e.stopPropagation(); else //不然,咱们须要使用IE的方式来取消事件冒泡 window.event.cancelBubble = true; }
preventDefault它是事件对象(Event)的一个方法,做用是取消一个目标元素的默认行为。既然是说默认行为,固然是元素必须有默认行为才能被取消,若是元素自己就没有默认行为,调用固然就无效了。什么元素有默认行为呢?如连接<a>
,提交按钮<input type=”submit”>
等。当Event 对象的 cancelable为false时,表示没有默认行为,这时即便有默认行为,调用preventDefault也是不会起做用的。htm
javascript的return false只会阻止默认行为,而是用jQuery的话则既阻止默认行为又防止对象冒泡。
//阻止浏览器的默认行为 总结 function stopDefault( e ) { //阻止默认浏览器动做(W3C) if ( e && e.preventDefault ) e.preventDefault(); //IE中阻止函数器默认动做的方式 else window.event.returnValue = false; return false; }