0

这是JSFiddle。

我正在尝试mouseenter使用以下功能在 Chrome、Firefox 等上工作:

var addMouseenter = (function () {
    var contains = function (parent, elem) {
            return parent.contains ? parent.contains(elem) :
                !!(parent.compareDocumentPosition(elem) & 16);
        },
        wrap = function (elem, method) {
            return function (e) {
                if (elem === e.target && !contains(elem, e.relatedTarget)) {
                    method.call(elem, e);
                }
            };
        };

    return function (elem, listener) {
        var listener2 = wrap(elem, listener);
        elem.addEventListener('mouseover', listener2, false);
    };
}());

一切正常,直到我遇到这种特定情况:

  • 元素 A 具有这些自定义mouseenter侦听器之一
  • 元素 A 包含元素 B
  • 元素 B 正好在元素 A 的边缘
  • 您在同一边缘输入元素 A

我的期望是该mouseover事件将在元素 B 上触发并冒泡到元素 A。但是,情况似乎并非如此。我使用 Chrome 13 和 Firefox 3.6 进行了测试,得到了相同的结果。我搞砸了什么吗?

4

2 回答 2

2

如果你不反对使用 jQuery:

$(document).ready(function() {
    $('#first').mouseover(function (e) {
        if ($(e.target).attr('id') != 'second') {
            alert('hello');
        }
    });
});

在您的 JSFiddle 中尝试过,它可以工作:当您进入绿色方块时,它不会触发;当你从外面进入红色方块时,它会开火;当您从绿色方块进入红色方块时,它会触发。这就是你想要的对吗?

新的 JSFiddle

或者保持你的 javascript 方法:

// Misc set-up stuff
var greet = function () { alert('Hi, my name is "' + this.id + '."'); },
    first = document.getElementById('first'),
    second = document.getElementById('second');

// The Actual Function
var addMouseenter = (function () {
    var contains = function (parent, elem) {
            return parent.contains ? parent.contains(elem) :
                !!(parent.compareDocumentPosition(elem) & 16);
        },
        wrap = function (elem, method) {
            return function (e) {
                //if (elem === e.target && !contains(elem, e.relatedTarget)) {
                if (elem === e.target && (e.target != second)) {
                    method.call(elem, e);
                }
            };
        };

    return function (elem, listener) {
        var listener2 = wrap(elem, listener);
        elem.addEventListener('mouseover', listener2, false);
    };
}());

// GOGOGO
addMouseenter(first, greet);

http://jsfiddle.net/AUc88/

于 2011-08-07T00:03:45.533 回答
0

The reason my custom function wasn't firing is because it didn't work.

I updated the fiddle showing that all is as it should be.

My mistake was only checking to see if e.target was the same as the element I had attached the listener to. What I needed to be checking was if they were the same or if e.target was a child of the element.

When you mouse over the two squares really quickly, it only registers the mouseover event on the inner one, and because my listener was attached to the outer one, the elem === e.target test was failing.

So I changed the if code in the wrap function to this:

if ((elem === e.target || contains(elem, e.target)) &&
    !contains(elem, e.relatedTarget)) {
        e.stopPropagation();
        method.call(elem, e);
}
于 2011-09-01T22:09:51.627 回答