在函数中将事件作为参数添加,使用addEventListener(在Firefox / IE中无效)

9
<html>
<head>
<title>FML</title>

<script type="text/javascript">

function function1(e, div) {
div.innerHTML="this works"
document.getElementById('myspan').innerHTML= 'x-pos on click: ' + e.clientX
div.addEventListener("mousemove", function(){test(event, this)}, true);
}

function test(e, div) {
div.innerHTML+='<br/>so does this'
//This doesn't work. Can't add event as a parameter to function that has to be executed when using addEventListener
document.getElementById('myspan2').innerHTML= 'y-pos on move: ' + e.clientY
}

</script>
</head>
<body>
<span id="myspan">&nbsp;</span>
<span id="myspan2">&nbsp;</span>
<div style="width:100px;height:100px;background-color:blue;overflow:hidden;"  onclick="function1(event, this)">
</body>
</html>

点击蓝色div。

我想添加mouseover事件,使其执行test()函数,该函数应包含以下参数:this,event。

当调用test(e, div)函数时,在Firefox和IE中会出现“事件未定义”的错误,尽管在Chrome和Safari中完美地工作。

有没有办法通过使用addEventListener添加事件参数?我可以在Chrome和Safari中使用window.event使其正常工作,但这是我想要的确切设置。 我已经搜索了一段时间并进行了试错,但没有成功… 所以FML:/ 除了朝自己的头部开枪之外,还有什么提示/提示/…吗?

我知道jQuery可能会解决所有这些问题,但我想在迁移到jQuery之前熟练掌握Javascript。或者我应该无论如何进行迁移吗?


1
除了我的回答外,还要点赞“我知道jQuery可能会解决所有问题,但在迁移到jQuery之前,我想熟练掌握JavaScript。”这是学习一门语言的正确方式。而且在JS社区中似乎很少见。因为我在SO上看到过人们甚至要求在jQuery中创建特殊结构来替代if-then-else... :-D - Imp
2个回答

13
div.addEventListener("mousemove", function(){test(event, this)}, true);

当然会出现 "event is undefined" 的错误!因为当 mousemove 事件触发时,会调用你的事件处理程序:

function(){test(event, this)}

获取事件信息对象有两种方法:一种是将其作为参数传递给事件处理程序,另一种是从 window.event 中找到它。

假设第二个情况成立。由于在您的函数中没有名为 event 的局部变量,并且调用它的 function1 中也没有这样的变量,因此浏览器会查找全局对象是否定义了 event。在JavaScript中,全局对象称为 window,因此您的函数被解释为:

function(){test(window.event, this)}

它可以正常工作。

然而,如我之前所指出的,在某些浏览器中,事件信息是通过参数传递的。因此,您的事件处理程序可能应该像这样:

function(event){test(event, this)}

否则传递给test()的事件将是未定义的。因此,以下是如何创建跨浏览器处理程序的方法:

否则传递给test()的事件将是未定义的。因此,以下是如何创建跨浏览器处理程序的方法:

function(event) {
  if (!event) // i.e. the argument is undefined or null
      event = window.event;

  test(event, this);
}
第二个问题是addEventListener()在旧版本的IE浏览器上不起作用(虽然在IE9中可以使用)。对于旧版本的IE浏览器,您必须使用类似的函数attachEvent()。或者,如果只附加一个处理程序,可以使用简单的方法。
div.onmousemove = function() {...};

哇,谢谢!这个问题困扰我很久了,从没想过会有解决的办法。看来你是一个纯粹主义者 :) 不过我已经转向使用jQuery了,但对于一些小东西我仍然(幸运地)使用JavaScript,这样就不必加载整个(jQuery)库了。 - Pascalculator
使用这种方法可以删除事件监听器吗?否则,以这种方式嵌套命名函数在匿名函数中的目的是什么? - Pasha Skender

2
在一些浏览器(如Firefox)中,必须将事件作为参数传递,因此您需要替换此代码。
div.addEventListener("mousemove", function(){test(event, this)}, true);

使用这个

div.addEventListener("mousemove", function(event){test(event, this)}, true);

仔细比较这两行代码,注意作为第二行函数参数传递的事件属性。对于旧版本的IE,必须使用attachEvent()
div.attachEvent("onclick", function(event){test(event, this)});

请注意,现代标准 JavaScript 中已经用addEventListener 替代了 attachEvent,现在几乎所有的现代浏览器都支持它。

可以在http://caniuse.com/#feat=addeventlistener上查看兼容性表格。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接