Cha*_*l72 4 html javascript javascript-events internet-explorer-8
我注意到一个奇怪的Javascript错误,它似乎只发生在Internet Explorer 8上.基本上,在IE-8上,如果你有一个事件处理函数捕获闭包中的事件对象,事件"type"属性似乎变得无效从关闭内部.
这是一个简单的代码片段,可以重现错误:
<html>
<head>
<script type="text/javascript">
function handleClickEvent(ev)
{
ev = (ev || window.event);
alert(ev.type);
window.setTimeout(function() {
alert(ev.type); // Causes error on IE-8
}, 20);
}
function foo()
{
var query = document.getElementById("query");
query.onclick = handleClickEvent;
}
</script>
</head>
<body>
<input id="query" type="submit" />
<script type="text/javascript">
foo();
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
所以基本上,这里发生的是在handleClickEvent函数中,我们有事件对象ev.我们打电话alert(ev.type),我们看到事件类型是"点击".到现在为止还挺好.但是当我们在一个闭包中捕获事件对象,然后alert(ev.type)再从闭包内再次调用时,现在突然出现Internet Explorer 8错误,因为表达式说"成员未找到" ev.type.type在我们捕获闭包中的事件对象之后,似乎事件对象的属性神秘地消失了.
我在Firefox,Safari和Chrome上测试了此代码段,但没有一个报告错误情况.但是在IE-8中,事件对象在关闭时被捕获后似乎变得无效.
问题:为什么在IE-8中发生这种情况,是否有解决方法?
是的,这是因为事件数据结构是IE8中的全局变量,所以当它们发生时它会被其他事件覆盖.如果你需要它来保持闭包,你将不得不在闭包中制作事件数据结构的实际副本,这样你就可以引用静态副本而不是IE8重用的一个全局结构.
制作数据结构的副本包括创建一个新对象并复制所有属性.如果任何属性本身是对象或数组,您也必须复制它们(只需将它们分配给新对象将分配引用,而不是副本).
或者,如果您只需要type,那么只需将其分配给type闭包中的局部变量,并像这样引用它.
function handleClickEvent(ev)
{
ev = (ev || window.event);
// save copy of type locally so we can use it later in setTimeout()
var type = ev.type;
alert(type);
window.setTimeout(function() {
alert(type);
}, 20);
}
Run Code Online (Sandbox Code Playgroud)