我有三个div框
第一个div主的ID为"main"
,其中包含另外两个标识为"menu_header"
且"menu_options"
这是我的HTML
<div id="main">
<div id="menu_header">
</div>
<div id="menu_options">
</div>
</div>
<span>Something here</span>
这是我的CSS
#main{
display:table-cell;
position:relative;
top:100px;
border:solid purple;
}
#menu_header{
position:relative;
border:solid black;
background:red;
width:100px;
top:200px;
height:100px;
/* -moz-transition-property:bottom;
-moz-transition-duration:2s;
transition-property:top;
transition-duration:1s;*/
}
#menu_options{
background:blue;
position:absolute;
bottom:0%;
border:solid black;
width:100px;
height:100px;
}
/*#menu_header:active{
top:100px;
}*/
(忽略css过渡,因为它被注释掉了)
这是我的javascript
function test(e){
//if(e.target.id=="menu_options"){return};
$('#menu_header').animate({top:'-10'},1000);
//var t=document.getElementById('menu_header')
// t.setAttribute('top','40px');
t.style="position:relative;border:solid black;background:red;width:100px;top:60px;height:100px;"
}
document.getElementById('main').addEventListener('click',test,false)
最后这是我的实验室鼠标jsfiddle链接 http://jsfiddle.net/repzeroworld/ev7k688s/
在这种情况下,当我在我的父容器上设置一个id为"main"
的点击事件处理程序时,除了点击这个父ID为"menu_options"
的容器子div之外,一切都运行正常还会触发处理程序
我在下面找到了这个链接,但不知怎的,这里的event.propogation()
解决方案似乎不适用于我的情况。
clicking on child element also triggers click event on it parent
一个令人讨厌的黑客攻击,以防止在子div捕获事件时执行任何操作
if(e.target.id=="menu_header"){return};
以上我在我的javascript代码中注释掉了。
问题:
尽管我在"menu_options"
上设置了"main"
以防止事件冒泡,但为什么ID为false
的子div从父容器中捕获了标识为add EventListener
的事件。
答案 0 :(得分:3)
原因
将false
传递给.addEventListener()
不会禁用冒泡。它只是使事件在冒泡阶段而不是捕获阶段发生。
当事件发生时,它从DOM的根开始并进入“捕获”阶段。这意味着事件从document
发送到event.target
,触发它在路上找到的任何“捕获”处理程序。
一旦到达event.target
,它就会反转过程,然后遍历到document
,调用它找到的任何“冒泡”处理程序。
因为你传递false
作为第三个参数,处理程序将在最后一个“冒泡”阶段被调用。
所以你看,这并没有阻止嵌套元素调用处理程序。
解决方案
如果只想要在单击实际元素时调用处理程序,而没有其子代,只需在this
不等于e.target
时停止处理程序。
function test(e){
if (this != e.target)
return;
$('#menu_header').animate({top:'-10'},1000);
var t=document.getElementById('menu_header')
t.setAttribute('top','40px');
t.style="position:relative;border:solid black;background:red;width:100px;top:60px;height:100px;"
}
document.getElementById('main').addEventListener('click',test,false)
答案 1 :(得分:1)
您可以按2场景限制事件冒泡。 1.将Click事件放在每个DOM对象上,表示子对象为父对象并放入event.stropPropagation()。 2.使用e.target.id识别DOM对象并返回“false”。[我们正在使用此]
以下代码
<script>
function test(e) {
if (e.target.id == "menu_header") { return }
else if (e.target.id == "menu_options") { return }
$('#menu_header').animate({ top: '-10' }, 1000);
var t = document.getElementById('menu_header')
t.setAttribute('top','40px');
t.style = "position:relative;border:solid black;background:red;width:100px;top:60px;height:100px;"
}
window.onload = function () {
document.getElementById('main').addEventListener('click', test, false);
}
</script>
答案 2 :(得分:1)
尝试停止在子元素中传播。请参阅here。
function test(){
$('#menu_header').animate({top:'10'},1000);
//var t=document.getElementById('menu_header')
// t.setAttribute('top','40px');
//t.style="position:relative;border:solid black;background:red;width:100px;top:60px;height:100px;"
}
function stopPropagation(e){
e.stopPropagation();
}
document.getElementById('main').addEventListener('click',test,false);
document.getElementById('menu_header').addEventListener('click',stopPropagation,false);