-
09-06-2019 - |
题
我正在使用 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(它使用 scriptaculous):
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;
}
这看起来很简单,但我就是无法理解它。
解决方案
我会给容器 div:
position: relative;
并在容器中添加第三个 div(应该是容器的最后一个子元素):
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
并捕获此 div 上的 mouseover 和 mouseout 事件。
因为它没有子元素,所以您不应该将虚假的 mouseover 和 mouseout 事件传播到它。
编辑:
我认为发生的情况是,当光标从父元素移动到子元素上时,父元素上会发生 mouseout 事件,子元素上会发生 mouseover 事件。但是,如果子元素上的鼠标悬停处理程序没有捕获该事件并阻止其传播,则父元素也将收到鼠标悬停事件。
其他提示
听起来你真正想要的是 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 中的一些边缘情况。
这可能不是最好的解决方案,但您可以设置一个全局布尔变量,两个方法都可以访问该变量,该变量仅指定最后一个操作是 HoverIn 还是 HoverOut。您可以使用此布尔变量来确定代码是否应该运行。
if (bWasHoverIn){
...
}
onmouseover 事件不应该在图像 div 上,而 onmouseout 事件不应该在文本 div 上吗?
@Ryan 布尔值并没有真正的帮助,它只是避免了循环,但是鼠标悬停事件仍然被触发并且文本被隐藏。
@Brian 它曾经是这样的,但它的行为方式是一样的。
我不确定这是否适合您的其余样式,但也许如果您更改了文本 div 上的 css,使其与图像大小相同,或者固定了外部 div 的大小,那么当鼠标悬停时事件触发后,外部 div 的大小不会发生太大变化而导致 mouseout 事件。
这有道理吗?