尽管有stopPropagation()和cancelBubble,事件仍然由孩子触发

时间:2011-07-18 19:54:34

标签: javascript dom javascript-events

我有一个元素(包含我的页面标题),它有一个onmouseover事件,将标题淡入菜单。它还有一个onmouseout事件,反过来。菜单本身就是一堆链接和图像。当鼠标进入时,它会像预期的那样消失。但是,当我在 <div>内的元素之间移动鼠标时,onmouseout事件由我要离开的元素触发,然后是我正在输入的元素的onmouseover事件。我试图使用stopPropagation和cancelBubble来阻止它,但无济于事。以下是相关代码:

Javascript(存储在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);
}

function 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(元素最初显示标题):

<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>

2 个答案:

答案 0 :(得分:0)

stopPropagation()可以使cancelBubble()停止冒泡,从孩子到没有冒泡的祖先,因为冒泡从未发生过。它是菜单内部元素上的mouseover和mouseout事件,最终冒泡到菜单元素。我觉得这样的事可能适合你:

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

此外,您不应该在setTimeout中使用字符串。你的字符串得到eval()'d,与传递函数相比,这是非常慢的。特别是像你的一些长串。你想要:

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);
}

答案 1 :(得分:0)

问题是你只是将处理程序附加到外部“menu”元素。其处理程序取消传播的事实并不重要;到那时为时已晚。

你可以做的是检查事件的“目标”属性,只有当它是正确的元素时才会响应。