Firefox与IE事件处理差异及自动获取event对象的解决方案

作者:像素猫时间:2026-10-25 08:54:20浏览:254

本文深入解析了Internet Explorer与Firefox在事件处理机制上的核心差异,指出IE将事件对象作为全局window.event保存,而Firefox则通过参数传递。针对直接调用onclick="foo()"无法获取event的问题,文章提供了手动传递event和自动查找event两种解决方案,重点推荐了基于caller链自动查找event对象的兼容函数,以实现跨浏览器的统一处理。

IE与Firefox事件处理机制差异

IE与Firefox在事件处理机制上存在显著差异。


在IE浏览器中,事件对象被维护为一个全局变量。


无论是用户触发的还是其他来源的事件,都会更新window.event对象。


因此,在代码中只需调用window.event即可获取事件对象,并通过event.srcElement属性取得触发事件的元素以进行后续处理。


而在Firefox中,事件对象并非全局对象,通常遵循“发生即使用”的原则。


Firefox会将事件对象自动传递给对应的事件处理函数,因此函数的第一个参数即为Firefox下的事件对象。


以上是对两种浏览器事件处理方法的初步理解,可能表述不够详尽,下面通过代码进行详细说明。


具体代码如下所示:


代码如下:

 
<button id="btn1">按钮1</button>
<button id="btn2">按钮2</button>
<button id="btn3">按钮3</button>
<script>
window.onload=function(){
document.getElementById("btn1").onclick=foo1
document.getElementById("btn2").onclick=foo2
document.getElementById("btn3").onclick=foo3
} 
function foo1(){
//在IE中,window.event是全局对象
alert(window.event) // IE下显示 "[object]",Firefox下显示 "undefined"
//在Firefox中,第一个参数自动作为事件对象
alert(arguments[0]) // IE下显示 "undefined",Firefox下显示 "[object]"
} 
function foo2(e){
alert(window.event) // IE下显示 "[object]",Firefox下显示 "undefined"
//注意,我从未给foo2传递参数。现在Firefox自动将参数e传递给foo2,该参数即为事件对象
alert(e) // IE下显示 "undefined",Firefox下显示 "[object]"
} 
function foo3(){ //同时兼容IE和Firefox的写法,用于获取事件对象
alert(arguments[0] || window.event) // IE和Firefox下均显示 "[object]"
var evt=arguments[0] || window.event
var element=evt.srcElement || evt.target // 在IE和Firefox下获取btn3对象
alert(element.id) // 输出 btn3
} 
</script>

直接调用onclick="foo()"的问题分析

看到这里,我们似乎已经理解了IE和Firefox的事件处理方式,并找到了解决办法。


但是,事情并没有结束。


请看下面的代码示例:


代码如下:

 
<button id="btn" onclick="foo()">按钮1</button>
<script>
function foo(){
alert(arguments[0] || window.event)
} 
</script>

不幸的是,foo返回的结果是undefined,而非预期的object。


原因在于事件绑定的方式不同。


onclick="foo()"是直接执行foo()函数,且没有传递任何参数。


在这种情况下,Firefox没有机会向foo传递任何参数。


而btn.onclick=foo这种绑定方式,因为不是直接执行函数,Firefox才有机会将参数传递给foo。


获取event对象的两种解决方案

解决方法如下:


方法一:这是一种较为笨拙的方法,既然Firefox没有机会传递参数,那么我们可以手动传递。



代码如下:

 
<button id="btn" onclick="foo(event)">按钮</button>
<script>
function foo(){
alert(arguments[0] || window.event)
var evt=arguments[0] || window.event
var element=evt.srcElement || evt.target
alert(element.id)
} 
</script>

方法二:自动查找event对象。


代码如下:

 
<button id="btn4" onclick="foo4()">按钮4</button>
<script>
function foo4(){
var evt=getEvent()
var element=evt.srcElement || evt.target
alert(element.id)
} 
function getEvent(){ //同时兼容IE和Firefox的写法
if(document.all) return window.event;
func=getEvent.caller;
while(func!=null){
var arg0=func.arguments[0];
if(arg0){
if((arg0.constructor==Event || arg0.constructor ==MouseEvent)
|| (typeof(arg0)=="object" && arg0.preventDefault && arg0.stopPropagation)){
return arg0;
} 
} 
func=func.caller;
} 
return null;
} 
</script>

方法二由lostinet原创,我在其基础上进行了改进,原始函数如下:


代码如下:

 
function SearchEvent()
{ 
//IE
if(document.all)
return window.event;
func=SearchEvent.caller;
while(func!=null)
{ 
var arg0=func.arguments[0];
if(arg0)
{ 
if(arg0.constructor==Event)
return arg0;
} 
func=func.caller;
} 
return null;
} 

简单总结:


上述两种解决方法均能正确处理Firefox和IE下的事件处理(无论是onclick="foo()"方式还是onclick=foo方式)。


但个人建议使用getEvent()方法来统一处理事件问题。

作者最新文章