Firefox事件目标元素与Chrome和IE不同



你好,我有一个问题,要定义称为我功能的目标。让我用一些代码解释自己。我有以下HTML代码:

<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quid de Platone aut de Democrito loquar? Hoc non est positum in nostra actioneLorem ipsum dolor sit amet, consectetur adipiscing elit. 
<span class="link" onmouseover="Test()"><b>Test link</b></span>
Quid de Platone aut de Democrito loquar? Hoc non est positum in nostra actioneLorem ipsum dolor sit amet, consectetur adipiscing elit. Quid de Platone aut de Democrito loquar? Hoc non est positum in nostra actioneLorem ipsum dolor sit amet, consectetur adipiscing elit. Quid de Platone aut de Democrito loquar? Hoc non est positum in nostra actione
</p>

在本段中,有 <span>包含事件侦听器。我想知道哪个目标(因为在我的生产环境中,我有多个对我的Test函数调用的对象)触发函数调用。

因此,我使用以下JavaScript代码:

if (!document.addEventListener) {
  document.attachEvent('onmousemove', displayPos);
} else {
  document.addEventListener('mousemove', displayPos, false);
}
function displayPos(e) {
    e_ff = e || window.event;       
}
function Test(){
    var target = "";
    if ( $.browser.mozilla == true) {           
        target = e_ff.target;           
    }
    else{           
        target = window.event.target || window.event.srcElement;
    }       
    console.log(target);
}

Chrome和IE中目标的输出是:<b>Test link</b>

Firefox中目标的输出为:不需要的<p></p>

在Firefox中是否有办法,不知道触发器的兄弟姐妹,以获得与Chrome和IE中完全相同的目标?

也许要注意。我无法通过Test()传递任何属性,因此我需要创建addEventListener函数。

演示可用:jsfiddle

您的代码有多个大问题。其中有些是您为浏览器兼容而做出不正确的努力。我将按顺序列出它们:

1。不正确定义全局变量e_ff(首先使用它)

为了清楚起见,如果您需要使用全局变量,请正确声明,理想情况下在文档的顶部。

// Global refference on last mousemove event
var e_ff;

2。在Google Chrome,Opera等中使用window.event

您的病情:

if ( $.browser.mozilla == true) {           
    // Firefox 
}
else{   
    // Chrome, IE, Opera       
    target = window.event.target || window.event.srcElement;
}   

window.event是一个长期弃用的IE仅功能。长期以来,我的意思是,即使IE也可能不再使用它。

偶数如果它有效,它仍然会导致不同的行为,因为在IE中,window.event的值取决于上下文。您会在 e_ffwindow.event中找到其他事件。

3。不正确使用事件回调

如果您确实需要使用onXXXX HTML属性,请注意,在回调值中可用两个变量:

  • this-转到元素(<a onclick="alert(this.title)" title="Hello :)">Try me</a>
  • event-转到事件对象(<a onclick="alert(event.button)">Try me</a>

因此,您应该这样做:

<span class="link" onmouseover="Test(this)"><b>Test link</b></span>
function Test(element) {
    console.log(element);
}

更好:

<span class="link" onmouseover="Test.call(this, event)"><b>Test link</b></span>
function Test(event) {
    console.log("Element ", this, "hovered and caused event: ",event);
}

我希望您注意到我完全放弃了全球鼠标的侦听器,因为它没有用。


解决方案而无需传递参数(因为op sustists 上方):

由于某种原因,您无法弄清楚如何传递参数,请使用全局变量,但要正确执行。我会这样做:

var lastHoverEvent = {element: null, event: null};
function registerLastHoverEvent(e) {
    lastHoverEvent.event = e;
    lastHoverEvent.element = this;
}

然后在Test方法之前调用它:

<p onmouseover="registerLastHoverEvent.call(this,event); Test();">Hover me</p>

在测试中使用它:

function Test() {
    console.log(lastHoverEvent.element);
}

JavaScript是单线线,因此上面没有种族条件。但是,该解决方案很荒谬,表明问题中有缺陷的逻辑。

它看起来确实像一个计时问题。您正在调用两个函数(处理程序,其他混合onMouseover和javaScript)。在FF中,您的鼠标可能不超出span/link/test()启动之前的跨度/链接。所以您可能想要:

document.getElementsByClassName("link")[0].addEventListener('mousemove', Test, false);

function Test(event){
  console.log(event.target);
}

甚至可能是"鼠标"。

最新更新