Reputation: 8402
I have three div boxes
The first div main has an id of "main"
and contains two other boxes with id "menu_header"
and "menu_options"
this is my html
<div id="main">
<div id="menu_header">
</div>
<div id="menu_options">
</div>
</div>
<span>Something here</span>
this is my 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;
}*/
(ignore css transition since it was commented out)
this is my 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)
finally this is my lab rat jsfiddle link http://jsfiddle.net/repzeroworld/ev7k688s/
In this scenario, when I set a click event handler on my parent container with id "main"
everything works perfectly except that whenever click on this parent's container child div with id "menu_options"
it also triggers the handler
I found the link below but somehow the event.propogation()
solution here seems not to work in my case.
clicking on child element also triggers click event on it parent
One nasty hack, to prevent the any actions from executing if the child div capture the event was
if(e.target.id=="menu_header"){return};
THe above I commented out in my javascript code.
Question:
why is the child div with id "menu_options"
capturing the event from the parent container with id "main"
despite me setting false
on add EventListener
to prevent event bubbling.?
Upvotes: 3
Views: 1684
Reputation:
The cause
Passing false
to .addEventListener()
does not disable bubbling. It simply makes it so that the event fires during the bubbling phase instead of the capturing phase.
When an event takes place, it starts at the root of the DOM and enters the "capturing" phase. This means that the event works its way from the document
to the event.target
, firing any "capturing" handlers it finds along the way.
Once it reaches the event.target
, it reverses course, and traverses back up to the document
, invoking any "bubbling" handlers it finds.
So because you passed false
as the third argument, the handler will be invoked during that last "bubbling" phase.
So you see, this does not do anything to prevent nested elements from invoking the handler.
The solution
If you only want to invoke the handler when clicking on the actual element, and none of its children, simply halt the handler if this
does not equal 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)
Upvotes: 3
Reputation: 1281
Try to stop propagation in the child element. See 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);
Upvotes: 1
Reputation: 824
You can restrict event bubbling by 2 scenario. 1. Put Click event on each DOM object, means child to parent and put event.stropPropagation(). 2. Identify the DOM object using e.target.id and return "false".[We are using this]
Code below
<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>
Upvotes: 1