我正在开发一个旧的应用程序,用于从IE8 / 9迁移到Firefox。它应该兼容两者。作为一个非常古老的应用程序,它不使用jquery。客户端也不想将jquery添加到此页面。我发现了一个奇怪的问题。以下是简单形式的示例
<html>
<head>
<script>
function test(){
console.log(event);
}
</script>
</head>
<body >
<button onclick="test()">Test</button>
</body>
</html>
&#13;
当我点击Test
按钮时,firefox会显示一个错误,即没有event
定义,因为IE显示的是默认事件。我的应用程序使用了很多这个事件对象。任何人都知道我怎么能在firefox中得到它?
答案 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.getElementById
,document.querySelector
等)获得的按钮HTMLElement的引用。
注意,在这种情况下,测试函数需要使用window.event
对象的事件回退(以使IE8满意):
function test(event) {
event = event || window.event;
console.log(event);
}
||
运算符确保事件将正确填充:在Firefox和IE9 + event
参数将可用,并且IE&lt; 9 event
参数将是未定义的{{1} } 将会被使用。