Move active element loses mouseout event in Internet Explorer

后端 未结 4 886
小蘑菇
小蘑菇 2020-12-10 03:31

In a library I am using I have the task of moving an element to the front of the dom when it is hovered over. (I make it bigger so I need to see it, then shrink it back when

相关标签:
4条回答
  • 2020-12-10 04:11

    That's wonky, and seems to be IE-only (but so is VML). If the parent element has a height specified, you can attach the mouseout handler to the parent... but it sounds like that won't work in your situation. Your best alternative is to use mouseover on adjacent elements to hide it:

    $(function()
    {
        $("li").mouseover(function()
        {
            $("li").css("border-color", "black");
            $(this).css("border-color", "red");
            this.parentNode.appendChild(this);
        });
    });
    

    Or SVG. You can use z-index in SVG.

    0 讨论(0)
  • 2020-12-10 04:35

    The problem is that IE handles mouseover differently, because it behaves like mouseenter and mousemove combined on an element. In other browsers it's just mouseenter.

    So even after your mouse has entered the target element and you've changed it's look and reappended it to it's parent mouseover will still fire for every movement of the mouse, the element gets reappended again, which prevents other event handlers from being called.

    The solution is to emulate the correct mouseover behavior so that actions in onmouseover are executed only once.

    $("li").mouseover( function() {
        // make sure these actions are executed only once
        if ( this.style.borderColor != "red" ) {
            this.style.borderColor = "red";
            this.parentNode.appendChild(this);
        }
    });
    

    Examples

    1. Extented demo of yours
    2. Example demonstrating the mouseover difference between browsers (bonus: native javascript)
    0 讨论(0)
  • 2020-12-10 04:35

    I was able to get it working with nested divs and a mouseenter event on the parent:

    <div id="frame">
      <div class='box'></div>
      <div class='box'></div>
      <div class='box'></div>
      <div class='box'></div>
    </div>
    ...
    $('#frame').mouseenter(function() {
         $(".box").css("border-color", "black");
    });
    

    Here's a working version using Raphael:

    http://jsfiddle.net/xDREx/

    0 讨论(0)
  • 2020-12-10 04:37

    I modified @galambalazs' answer because I found that it failed if I hovered really quickly over the li elements, as some of the elements would still retain the mouseover effect.

    I came up with a solution that removes the hover state on elements that failed to trigger the mouseover event by pushing these elements to a stack whenever the mouseover even is triggered. Anytime either the mouseover or mouseout event is called, I pop the elements from this array and remove the styles placed on it:

    $(function(){
    
        // Track any hovered elements
        window.hovered = [];
    
        $("li").mouseover(function() {
            // make sure that these actions happen only once
            if ( $(this).css("border-color") != "red" ) {
                resetHovered ();  // Reset any previous hovered elements
                $(this).css("border-color","red");
                this.parentNode.appendChild(this);
                hovered.push(this);
            }
        });
    
        $("li").mouseout(function(){
            resetHovered();  // Reset any previous hovered elements
        });
    
        // Reset any elements on the stack
        function resetHovered () {
            while ( hovered.length > 0 ) {
                var elem = hovered.pop();
                $(elem).css("border-color","black");
            }
        }
    });
    

    I've tested this solution with IE 11. A functional example can be found here.

    0 讨论(0)
提交回复
热议问题