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

时间:2016-06-20 09:28:35

标签: javascript jquery html firefox

您好我有一个关于定义调用我的函数的目标的问题。让我用一些代码解释一下自己。我有以下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

2 个答案:

答案 0 :(得分:0)

您的代码存在多个大问题。其中一些源于您对浏览器兼容性的不正确努力。我将按顺序列出它们:

1。没有正确定义全局变量e_ff(并且首先使用它)

为清楚起见, if 您需要使用全局变量,请将它们正确声明,最好是在文档的顶部。

// Global refference on last mousemove event
var e_ff;

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

你的情况:

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

window.eventlong deprecated IE only feature 。长期弃用我的意思是即使IE也可能不再使用它了。

即使如果它是有效的,它仍然会导致不同的行为,因为在IE中window.event的值取决于上下文。您会在IE中的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 坚持):

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

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是单线程的,因此上面没有竞争条件。然而,解决方案是荒谬的,表明问题中的逻辑存在缺陷。

答案 1 :(得分:-1)

它看起来像一个计时问题。你正在调用两个函数(处理程序,另外混合onmouseover和javascript)。在FF中,你的鼠标可能在测试()开始之前不在span / link /中。 所以你可能想要:

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

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

可能甚至&#34;鼠标悬停&#34;。