前段时间开辟一个小项目的时刻碰到一个题目,即给一个元素以及它的父元素绑定了click事宜,这个时刻我点击这个元素时,父级元素的clik事宜也会触发,这明显不符合请求。查阅了一些材料以后才晓得本来这就是事宜冒泡,下面是我对事宜冒泡和事宜捕捉的明白。
事宜冒泡:事宜从目的子元素向父级元素逐级通报(目的div -> 父元素 —> body ->html ->document)
事宜捕捉:事宜从最顶级元素向目的子元素逐级通报(document -> html -> body -> 父级元素 -> 目的div)
我明白的事宜捕捉和事宜冒泡实在就是浏览器事宜触发的两个阶段。
在不支撑w3c规范的浏览器(IE9以下)中,我们用attachEvent(event, fn)要领绑定一个事宜时,fn函数只能在冒泡阶段实行且只能在冒泡阶段实行。
在支撑w3c规范的浏览器中,我们用addEventListener(event, fn, useCapture)要领绑定一个事宜时,个中的useCapture参数即用来指定fn函数是在捕捉阶段实行照样在冒泡阶段实行,默许false为冒泡实行,ture为捕捉实行。一般为了兼容老版本的IE浏览器(IE以下),我们不设置useCapture参数,或设置成false
下面是示例代码
html代码:
<style type="text/css">
.parent {height: 120px; width: 120px; background-color: #999; padding: 25px;}
.child {height: 60px; width: 60px; background-color: #666}
</style>
<body>
<div class="parent" id="parent">
<div class="child" id="child"></div>
</div>
</body>
事宜冒泡js代码:
var parent = document.getElementById('parent')
var child = document.getElementById('child')
// click事宜冒泡时触发(useCapture参数为false和不加参数时的默许行动)
parent.addEventListener('click', function(e) {
console.log('parent')
}, false)
child.addEventListener('click', function(e) {
console.log('child')
// e.stopPropagation() // 阻挠事宜冒泡
}, false)
这个时刻点击child元素,控制台会顺次弹出child parent,因而事宜触发的递次是child ->parent, 固然假如我们愿望点击child元素以后不触发parent元素的click事宜,也能够用stopPropagation()来阻挠事宜的冒泡。
事宜捕捉js代码:
// click事宜捕捉时触发
parent.addEventListener('click', function(e) {
console.log('parent')
}, true)
child.addEventListener('click', function(e) {
console.log('child')
}, true)
这个时刻点击child元素,控制台会顺次弹出parent child,因而事宜触发的递次是parent->child
说了那末多,事宜冒泡终究有什么用呢? 下面我们就应用事宜冒泡道理来完成事宜托付
事宜托付:
什么是事宜托付? 事宜托付就是底本你要给一个元素绑定某个事宜,然则你不直接绑定在这个元素上,而是绑定在与它相干的元素上,然则效果与绑定在这个元素上一样。 如许做有什么优点呢? 下面我们做个小例子,当鼠标移动到li上时转变它的背景色彩,鼠标脱离时背景色彩恢复
html代码:
<body>
<ul id="parent">
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
<li>item5</li>
</ul>
</body>
js代码:
var oParent = document.getElementById("parent");
var oItem = oParent.getElementsByTagName("li");
// 给ul绑定鼠标移入事宜
oParent.addEventListener('mouseover', function(e) {
if(e.target.nodeName.toLowerCase() == "li"){
e.target.style.background = "red";
}
})
// 给ul绑定鼠标移出事宜
oParent.addEventListener('mouseout', function(e) {
if(e.target.nodeName.toLowerCase() == "li"){
e.target.style.background = "";
}
})
固然你会说我也能够应用轮回遍历为每一个li都绑定鼠标移入移出事宜,固然这是能够的,然则如许你的代码就多了一个轮回操纵,假如轮回多了以后对机能影响就不可疏忽了。
另有就是假如你又动态的增加了一个<li>标签,那末你又不得不为这个li标签零丁绑定事宜,而采纳事宜托付这些懊恼都能够省略。
本文参考文章:
js之事宜冒泡详解 http://www.jb51.net/article/4…
事宜托付及其道理 http://www.cnblogs.com/dearxi…