MouseEnter的全兼容

MouseEnter的全兼容写法

by superchangme

HTML

<div id="a" style="background:gold; width:100px; height:100px; padding:30px">
    <div style="background:gray; height:100%;"></div>
</div>
<textarea id="b" style="width:100px; height:100px;"></textarea>

CSS

/*
清晰网
kixi.com.cn
从javascript开始
*/

JavaScript

//mouseenter和mouseover的区别:两个都是当鼠标从元素外部移动到元素范围内时触发,不同的是mouseenter事件不冒泡,这样带来的效果就是鼠标移动到后代元素上不会触发这个元素的mouseenter事件,这样一方面可以避免事件冒泡带来的麻烦,另一方面也丢失了事件冒泡的优势比如借助事件冒泡实现事件委托以优化网页性能, 而mouseover事件恰好相反。

var ua = navigator.userAgent;
Test = {
    version: (ua.match(/.+(?:rv|it|ra|ie|me)[\/: ]([\d.]+)/i) || [])[1],
    ie: /msie/i.test(ua) && !/opera/i.test(ua),
    op: /opera/i.test(ua),
    sa: /version.*safari/i.test(ua),
    ch: /chrome/.test(ua),
    ff: /gecko/i.test(ua) && !/webkit/i.test(ua),
    wk: /webkit/i.test(ua),
    mz: /mozilla/i.test(ua) && !/(compatible|webkit)/i.test(ua)
}

function $(id) {
    return document.getElementById(id);
}

function addEvent(el, type, fn) {
    (el.attachEvent) ? (el.attachEvent("on" + type, fn)) : (el.addEventListener(type, fn, false));
};

var contains = document.compareDocumentPosition ? function (parent, child) {
        return !!(parent.compareDocumentPosition(child) & 16);
    } : function (parent, child) {
        return child !== child && (parent.contains ? parent.contains(child) : true);
    }

    function fixMouseLeave(elem, fn) {
        var mouseleave = Test.ie ? "mouseleave" : "mouseout";
        (elem == null || elem == window) && (elem = document);
        return {
            type: mouseleave,
            elem: elem,
            fn: Test.ie ? fn : function (e) {
                console.log(e.relatedTarget,this);
                (contains(e.relatedTarget, this)) && (fn.call(this, e));
            }
        }
    }

    function fixMouseEnter(elem, fn) {
        var mouseenter = Test.ie ? "mouseenter" : "mouseover";
        (elem == null || elem == window) && (elem = document);
        return {
            type: mouseenter,
            elem: elem,
            fn: Test.ie ? fn : function (e) {
                (contains(e.relatedTarget, this)) && (fn.call(this, e));
            }
        }
    }

var me = fixMouseEnter($("a"), function (e) {
    $("b").value += "enter\n";
});
var ml = fixMouseLeave($("a"), function (e) {
 ...