简体   繁体   English

mouseout 事件的问题

[英]Problems with mouseout event

I'm using JavaScript to hide an image and show some text thats hidden under it.我正在使用 JavaScript 来隐藏图像并显示一些隐藏在其下的文本。 But, when the text is shown if you scroll over it, it fires the mouseout event on the container, that then hides the text and shows the image again, and it just goes into a weird loop.但是,当文本显示时,如果你滚动它,它会在容器上触发 mouseout 事件,然后隐藏文本并再次显示图像,它只是进入一个奇怪的循环。

The html looks like this: 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>

And the javascript (It uses scriptaculous):和 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;
}

This seems really simple, but i just cant wrap my head around it.这看起来很简单,但我就是无法理解它。

I'd give the container div: 我给容器div:

position: relative;

and add a third div in the container (should be the last child of the container) with: 并在容器中添加第三个div(应该是容器的最后一个子节点):

position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;

and catch the mouseover and mouseout events on this div instead. 并在此div上捕获mouseover和mouseout事件。

Because it has no child elements, you shouldn't get spurious mouseover and mouseout events propagating to it. 因为它没有子元素,所以不应该将虚假鼠标悬停和mouseout事件传播给它。

Edit: 编辑:

What I believe happens, is that when the cursor moves from a parent element onto a child element, a mouseout event occurs on the parent element, and a mouseover event occurs on the child element. 我认为发生的是,当光标从父元素移动到子元素时,父元素上发生mouseout事件,并且子元素上发生鼠标悬停事件。 However, if the mouseover handler on the child element does not catch the event and stop it propagating, the parent element will also receive the mouseover event. 但是,如果子元素上的mouseover处理程序未捕获事件并停止传播,则父元素也将接收mouseover事件。

It sounds like what you really want is mouseenter / mouseleave (IE proprietary events, but easy to emulate): 听起来你真正想要的是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);

Alternatively, patch prototype.js and use mouseenter and mouseleave with confidence. 或者, 修补prototype.js并自信地使用mouseentermouseleave Note that I've expanded the check for leaving the window or entering XUL chrome; 请注意,我已经扩展了离开窗口或输入XUL镶边的检查; this seemed to fix some edge cases in Firefox for me. 这似乎为我修复了Firefox中的一些边缘情况。

This may not be the best solution but you could set a global boolean variable that would be accessible to both methods that would just specify if the last action was HoverIn or HoverOut. 这可能不是最好的解决方案,但您可以设置一个全局布尔变量,这两个方法都可以访问这些变量,只指定最后一个操作是HoverIn还是HoverOut。 You could use this boolean variable to determine if the code should run or not. 您可以使用此布尔变量来确定代码是否应该运行。

if (bWasHoverIn){
   ...
}

onmouseover事件不应该在图像div上,而onmouseout事件应该在文本div上吗?

@Ryan The boolean doesnt really help, it just avoids the loop, but the mouseover event is still fired and the text gets hiden. @Ryan布尔没有真正帮助,它只是避免循环,但鼠标悬停事件仍然被触发,文本被隐藏。

@Brian It used to be that way, but it behaved the same way. @Brian曾经是这样,但它的行为方式相同。

I'm not sure if this would fit with the rest of your styling, but perhaps if you changed the css on the text div so it was the same size as the image, or fixed the size of the outer div, then when the mouseover event fired, the size of the outer div wouldn't change so much as to cause the mouseout event. 我不确定这是否适合你的其他样式,但也许你改变文本div上的css,使其与图像大小相同,或者修改外部div的大小,然后当鼠标悬停时事件被触发后,外部div的大小不会发生太大而导致mouseout事件。

Does this make sense? 这有意义吗?

尝试使用onmouseenter而不是onmouseover和onmouseleave而不是onmouseout。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM