鼠标移出事件的问题
我正在使用JavaScript隐藏图像并显示隐藏在其下方的一些文本。但是,如果在滚动时显示文本,则会在容器上触发mouseout事件,然后隐藏该文本并再次显示图像,这只会进入一个怪异的循环。
html看起来像这样:
<div onmouseover="jsHoverIn('1')" onmouseout="jsHoverOut('1')"> <div id="image1" /> <div id="text1" style="display: none;"> <p>some content</p> <p>some more content</p> </div> </div>
和javascript(它使用脚本):
function jsHoverIn(id) { if(!visible[id]) { new Effect.Fade ("image" + id, {queue: { position: 'end', scope: id } }); new Effect.Appear ("text" + id, {queue: { position: 'end', scope: id } }); visible[id] = true; } } function jsHoverOut (id) { var scope = Effect.Queues.get(id); scope.each(function(effect) { effect.cancel(); }); new Effect.Fade ("text" + id, {queue: { position: 'end', scope: id } }); new Effect.Appear ("image" + id, {queue: { position: 'end', scope: id } }); visible[id] = false; }
这看起来真的很简单,但是我不能把头包住。
解决方案
回答
这可能不是最好的解决方案,但是我们可以设置一个全局布尔变量,这两个方法都可以访问这两个变量,它们仅指定最后一个动作是HoverIn还是HoverOut。我们可以使用此布尔变量确定代码是否应该运行。
if (bWasHoverIn){ ... }
回答
onmouseover事件不应该在图像div上,onmouseout事件不应该在文本div上吗?
回答
@Ryan布尔值并没有真正的帮助,只是避免了循环,但是mouseover事件仍然被触发并且文本被隐藏。
@Brian曾经是这种方式,但其行为方式却是相同的。
回答
我给容器div:
position: relative;
并在容器中添加第三个div(应为容器的最后一个子元素),并带有:
position: absolute; top: 0; bottom: 0; left: 0; right: 0;
并在此div上捕获mouseover和mouseout事件。
由于它没有子元素,因此不应散布虚假的mouseover和mouseout事件。
编辑:
我相信发生的是,当光标从父元素移动到子元素时,在父元素上发生mouseout事件,在子元素上发生mouseover事件。但是,如果子元素上的mouseover处理程序没有捕获到该事件并停止传播,则父元素也将收到mouseover事件。
回答
我不确定这是否适合其余样式,但是也许我们是否更改了文本div上的css,使其与图像大小相同,或者固定了外部div的大小,则将鼠标悬停触发事件后,外部div的大小变化不会太大,不会引起mouseout事件。
这有意义吗?
回答
听起来我们真正想要的是mouseenter
/mouseleave
(IE专有事件,但易于模拟):
// Observe mouseEnterLeave on mouseover/mouseout var mouseEnterLeave = function(e) { var rel = e.relatedTarget, cur = e.currentTarget; if (rel && rel.nodeType == 3) { rel = rel.parentNode; } if( // Outside window rel == undefined || // Firefox/other XUL app chrome (rel.tagName && rel.tagName.match(/^xul\:/i)) || // Some external element (rel && rel != cur && rel.descendantOf && !rel.descendantOf(cur)) ) { e.currentTarget.fire('mouse:' + this, e); return; } }; $(yourDiv).observe('mouseover', mouseEnterLeave.bind('enter')); $(yourDiv).observe('mouseout', mouseEnterLeave.bind('leave')); // Use mouse:enter and mouse:leave for your events $(yourDiv).observe(!!Prototype.Browser.IE ? 'mouseenter' : 'mouse:enter', yourObserver); $(yourDiv).observe(!!Prototype.Browser.IE ? 'mouseleave' : 'mouse:leave', yourObserver);
或者,对prototype.js进行补丁,并放心使用mouseenter
和mouseleave
。请注意,我已经扩大了离开窗口或者输入XUL chrome的支票;这似乎为我修复了Firefox中的一些极端情况。