Javascript events fixes on old Internet Explorer

Fix Internet Explorer handlers and add support to mouseenter and mouseleave

Demo
Demo
Demo and source code

Here is a fix for Javascript event that fixed two important problems on Internet Explorer 8 and lower:

  • Fix the scope of event handlers added with Internet Explorer's attachEvent method (code taken from Yui Library)
  • Add support to mouseenter and mouseleave events

Here is the javascript code:

// @function addEvent(obj:documentElement, evnt:string, fn:function, useCapture:boolean)
function addEvent(obj, evnt, fn, useCapture){
    // attachEvent for ie8- or addEventListener for modern browsers
    if(typeof obj.attachEvent != 'undefined'){
        // utils for attachEvent
        function getEvent(e, boundEl){
            var e = e || window.event;
            if(!e){
                var c = this.getEvent.caller;
                while(c){
                    e = c.arguments[0];
                    if(e && Event == e.constructor){
                        break;
                    }
                    c = c.caller;
                }
            }
            return e;
        }
        var wrappedFn = function(e){
            return fn.call(obj, getEvent(e, obj));
        }
        // attachEvent
        obj.detachEvent("on"+evnt, wrappedFn); 
        obj.attachEvent("on"+evnt, wrappedFn);
    }else{
        // utils for addEventListener
        function mouseEnter(fn){
            return function(evnt){
                var relTarget = evnt.relatedTarget;
                if(this == relTarget || isAChildOf(this, relTarget)){
                    return;
                }
                fn.call(obj, evnt);
            }
        }
        function isAChildOf(parent, child){
            if(parent == child){
                return false;
            }
            while(child && child !== parent){
                child = child.parentNode;
            }
            return child == parent;
        }
        // addEventListener
        if(evnt == 'mouseenter'){
            obj.removeEventListener('mouseover', mouseEnter(fn), useCapture);
            obj.addEventListener('mouseover', mouseEnter(fn), useCapture);
        }else if(evnt == 'mouseleave'){
            obj.removeEventListener('mouseout', mouseEnter(fn), useCapture);
            obj.addEventListener('mouseout', mouseEnter(fn), useCapture);
        }else{
            obj.removeEventListener(evnt, fn, useCapture);
            obj.addEventListener(evnt, fn, useCapture);
        }
    }
};

To use it just call the addEvent function like this:

// usage
addEvent(document, "mouseenter", function(e){
    alert(e.type);
}, false);