开发者

Events still being triggered by children despite stopPropagation() and cancelBubble

I have a <div> element (containing my page header) which has an onmouseover event that fades the header into a menu. It also has an onmouseout event that does the reverse. The menu itself is simply a bunch of links and images. When the mouse enters the <div>, it fades just as expected. However, when I move the mouse between elements within the <div>, the onmouseout event is triggered by the element I'm leaving, followed by the onmouseoverevent of the element I'm entering. I've tried to stop this using stopPropagation and cancelBubble, but to no avail. Here is the relevant code:

JavaScript (stored in menu.js):

//These two functions are for rendering the menu. 
//Fade is a function that fades an element out or in by 
//changing the opacity of the element.

function renderHeader() {
fade('menu');
setTimeout("document.getElementById('menu').innerHTML=\
\"<img src='menu_1.png' width=20% /><img src='menu_2.png' width=20% />\
<img src='menu_3.png' width=20% /><img src='menu_4.png' width=20% />\
<img src='menu_5.png' width=20% />\"",TimeToFade+33);
setTimeout("fade('menu')",TimeToFade+66);
}

fun开发者_Python百科ction renderMenu() {
fade('menu');
setTimeout("document.getElementById('menu').innerHTML=\
\"<a href='home.asp'><img src='menu_a.png' width=20% /></a>\
<a href='members.asp'><img src='menu_b.png' width=20% /></a>\
<a href='locations.asp'><img src='menu_c.png' width=20% /></a>\
<a href='about.asp'><img src='menu_d.png' width=20% /></a>\
<a href='services.asp'><img src='menu_e.png' width=20% /></a>\"",TimeToFade+33);
setTimeout("fade('menu')",TimeToFade+66);
}


//These two functions are responsible for stopping the propagation.
function load() {
  element = document.getElementById("menu");
  element.addEventListener("mouseover", stopEvent, false);
  element.addEventListener("mouseout", stopEvent, false);
}

function stopEvent(ev) {
  if (!ev) var ev = window.event;
  ev.cancelBubble = true;
  if (ev.stopPropagation) ev.stopPropagation();
}

HTML (the <div> element initially shows the header):

<head>
...
<script type="text/javascript" src="Scripts/menu.js"></script>
</head>

<body onload="load();">
<div id='menu' style="opacity:1;filter:alpha(opacity=100);height:150px"
onmouseover="renderMenu()" onmouseout="renderHeader()">
<img src='menu_1.png' width=20% /><img src='menu_2.png' width=20% />
<img src='menu_3.png' width=20% /><img src='menu_4.png' width=20% />
<img src='menu_5.png' width=20% /></div>


stopPropagation() can cancelBubble() stop bubbling up, from children to ancestors not bubbling down, since bubbling down never happens to begin with. It is the mouseover and mouseout event on you elements inside your menu that are eventually bubbling up to your menu element. I think something like this might work for you:

function load() {
  elements = document.getElementById("menu").getElementsByTagName('*');
  elements.addEventListener("mouseover", stopEvent, false);
  elements.addEventListener("mouseout", stopEvent, false);
}

Also, you shouldn't be using strings in your setTimeout. Your strings get eval()'d which is very slow compared to just passing in a function. Especially a long string like some of your's. You want:

function renderHeader() {
fade('menu');
setTimeout(function(){ document.getElementById('menu').innerHTML=\
"<img src='menu_1.png' width=20% /><img src='menu_2.png' width=20% />\
<img src='menu_3.png' width=20% /><img src='menu_4.png' width=20% />\
<img src='menu_5.png' width=20% />"; },TimeToFade+33);
setTimeout(function(){ fade('menu'); },TimeToFade+66);
}

function renderMenu() {
fade('menu');
setTimeout(function(){ document.getElementById('menu').innerHTML=\
"<a href='home.asp'><img src='menu_a.png' width=20% /></a>\
<a href='members.asp'><img src='menu_b.png' width=20% /></a>\
<a href='locations.asp'><img src='menu_c.png' width=20% /></a>\
<a href='about.asp'><img src='menu_d.png' width=20% /></a>\
<a href='services.asp'><img src='menu_e.png' width=20% /></a>"; },TimeToFade+33);
setTimeout(function(){ fade('menu'); },TimeToFade+66);
}


The problem is that you're only attaching the handler to the outer "menu" element. The fact that its handler cancels propagation doesn't matter; by that time it's too late.

What you can do instead is check the "target" property of the event, and only respond when it's the right element.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜