开发者

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

开发者 https://www.devze.com 2023-03-21 08:31 出处:网络
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 sim

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

精彩评论

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

关注公众号