Firefox中的默认事件对象?

时间:2014-12-11 14:06:45

标签: javascript internet-explorer firefox javascript-events internet-explorer-9

我正在开发一个旧的应用程序,用于从IE8 / 9迁移到Firefox。它应该兼容两者。作为一个非常古老的应用程序,它不使用jquery。客户端也不想将jquery添加到此页面。我发现了一个奇怪的问题。以下是简单形式的示例



<html>
	<head>
		<script>
			function test(){
				console.log(event);
			}
		</script>
	</head>
	<body >
		<button onclick="test()">Test</button>
	</body>
</html>
&#13;
&#13;
&#13;

当我点击Test按钮时,firefox会显示一个错误,即没有event定义,因为IE显示的是默认事件。我的应用程序使用了很多这个事件对象。任何人都知道我怎么能在firefox中得到它? enter image description here

2 个答案:

答案 0 :(得分:4)

您的代码依赖于IE事件模型,该模型为每个事件创建一个全局 window.event 对象。它被弃用以支持W3C事件模型(由Firefox和其他人支持),但在IE中仍然支持向后兼容性。

您需要将事件对象传递给函数:

<button onclick="test(event)">Test</button>

然后在函数中:

function test(event){
    alert(event);
}

如果使用 addEventListner 附加侦听器,则默认情况下将事件对象作为第一个参数传递给侦听器:

document.querySelector('#buttonID').addEventListener('click', test, false);

您还可以直接将侦听器添加为属性:

document.querySelector('#buttonID').onclick = test;

将事件对象作为W3C事件模型中的第一个参数传递,但不在IE中,因此如果 event 未定义,该函数必须测试并使用 window.event

function test(event){
    event = event  || window.event;
    console.log(event);
}

添加适用于所有浏览器的侦听器的一个非常简单的功能是:

function addEvent(element, event, fn) {
  if (element.addEventListener) {
    element.addEventListener(event, fn, false);
  } else if (element.attachEvent) {
    element.attachEvent('on' + event, fn);
  }
}

请注意,在IE中,不会设置为调用该事件的元素。如果您需要解决这个问题,那么以下内容将会这样做:

function addEvent(element, evt, fn) {
  if (element.addEventListener) {
    element.addEventListener(evt, fn, false);
  } else if (element.attachEvent) {
    element.attachEvent('on' + evt, function() {
      fn.call(element, event);
    });
  }
}

并使用它:

addEvent(document.getElementById('buttonID', 'click', test);

还有更复杂的版本,但上述内容应该足够了。它会创建不必要的循环引用,您可能希望避免这些。要做到这一点,你需要像:

function addEvent(element, evt, fn) {
  if (element.addEventListener) {
    element.addEventListener(evt, fn, false);
  } else if (element.attachEvent) {
    element.attachEvent('on' + evt, (function(fn, element) {
      return function() {
        fn.call(element, event);
      };
    }(fn, element)));
  }
  // Remove obvious circular reference
  element = null;
}

最重要的是,在绝大多数情况下,添加侦听器作为属性很简单,跨浏览器并且足够。如果您需要为同一事件的元素添加多个侦听器,它才会失败,但即使这样也很容易适应。

答案 1 :(得分:3)

实施中存在跨浏览器差异。 IE使用(并且仍然使用)window.event对象,而Firefox从未以这种方式实现它。而Firefox支持将事件对象传递到事件处理程序。试试这个:

function test(event) {
    console.log(event);
}

并在HTML中:

<button onclick="test(event)">Test</button>

作为另一种可能性,由于您必须支持IE8,您可以通过直接分配onclick函数来将事件注册为属性:

buttonObject.onclick = test;

其中buttonObject是对使用某种DOM方法(document.getElementByIddocument.querySelector等)获得的按钮HTMLElement的引用。

注意,在这种情况下,测试函数需要使用window.event对象的事件回退(以使IE8满意):

function test(event) {
    event = event || window.event;
    console.log(event);
}

||运算符确保事件将正确填充:在Firefox和IE9 + event参数将可用,并且IE&lt; 9 event参数将是未定义的{{1} } 将会被使用。