Onmouseover child div problem and event bubbling

后端 未结 1 1272
忘掉有多难
忘掉有多难 2021-01-07 01:26

I have a small div above (hover) a big one.
I assign onmouseover and onmouseout events to the wrapper div.
For image caption roll-over animation.

The proble

相关标签:
1条回答
  • 2021-01-07 02:13

    This article on quirksmode ( near the bottom ) has an explanation of what you are experiencing and a script that might help you. There is a lot of cross browser info regarding mouse events too

    OK, here's some working code. I don't promise this is the most efficient or that it won't cause memory leaks in IE (or that it works in IE - please let me know ). This is why people use libraries, much safer and easier.

    // a general purpose, cross browser event adder
    // returns a function that if run removes the event
    function addEvent( el, eventType, handler, capturing ) {
        if( el.addEventListener ) {
            el.addEventListener( eventType, handler, capturing || false );
            var removeEvent = function() { el.removeEventListener( eventType, handler, capturing || false ) };
        } else if( el.attachEvent ) {
            var fn = function() {
                handler.call( el, normalise( window.event ) );
            };
            el.attachEvent( 'on'+eventType, fn );
            var removeEvent = function(){ el.detachEvent( 'on'+eventType, fn ) };
        }
        function normalise( e ) {
            e.target = e.srcElement;
            e.relatedTarget = e.toElement;
    
            e.preventDefault = function(){ e.returnValue = false };
            e.stopPropagation = function(){ e.cancelBubble = true };
            return e;
        };
        return removeEvent;
    };
    
    
    
    // adds mouseover and mouseout event handlers to a dom element
    // mouseover and out events on child elements are ignored by this element
    // returns a function that when run removes the events
    // you need to send in both handlers - an empty function will do
    function addMouseOverOutEvents( element, overHandler, outHandler ) {
    
        function out( e ) {
            var fromEl = e.target;
            var toEl = e.relatedTarget;
            // if the mouseout didn't originate at our element we can ignore it
            if( fromEl != element ) return;
            // if the element we rolled onto is a child of our element we can ignore it
            while( toEl  ) {
                toEl = toEl.parentNode;
                if( toEl == element ) return;
            }
            outHandler.call( element, e );
        }
    
        function over( e ) {
            var toEl = e.target;
            var fromEl = e.relatedTarget;
            // if the mouseover didn't originate at our element we can ignore it
            if( toEl != element ) return;
            // if the element we rolled from is a child of our element we can ignore it
            while( fromEl  ) {
                fromEl = fromEl.parentNode;
                if( fromEl == element ) return;
            }
            overHandler.call( element, e );
        }
    
        var killers = [];
        killers.push( addEvent( element, 'mouseover', over ) );
        killers.push( addEvent( element, 'mouseout', out ) );
        return function() {
            killers[0]();
            killers[1]();
        }
    }
    

    Example of use:

    // add the events
    var remover = addMouseOverOutEvents(
        document.getElementById( 'elementId' ),
        function( e ) {
            this.style.background = 'red';
            console.log( 'rolled in: '+e.target.id );
        },
        function( e ) {
            this.style.background = 'blue'
            console.log( 'rolled out: '+e.target.id );
        }    
    );
    
    //remove the events
    remover();
    
    0 讨论(0)
提交回复
热议问题