这似乎在 Firefox 中工作正常,但是,特别是在 IE8 中(它可能在其他版本的 IE 中工作),我遇到了事件变量丢失的问题。
有一个事件(mousedown)调用存储参数集的函数。参数之一是事件本身。被调用的函数将参数存储在全局变量中,以便在 settimeout 中调用的函数可以访问它们。
一旦执行,设置超时调用的函数就不再能够访问事件变量中的属性。它仍然被识别为事件对象,但所有属性都被重置。
我尝试过使用函数引用,使用匿名函数,既使用全局变量,又将它们作为参数传递,但似乎没有任何效果。有人有什么想法吗?
我知道这有点复杂,所以我设置了一个简单的示例来显示我的问题: http://jsfiddle.net/fd8sk/
当您单击“立即触发”(不使用设置超时)时,您会发现按钮单击是一个数字。当您单击“触发延迟”时,该按钮现在为“未知”。
这是一个非常通用的函数,有很多并不总是使用的参数,所以我希望避免对此进行重大重构。在我的真实示例中,在我的问题案例中作为事件的参数在其他场景中不会是事件。
最佳答案
onmousedown="eventFired(event);"
在 IE<9 的事件模型中执行的操作与在其他浏览器中执行的操作略有不同。
在大多数浏览器中,上述内容都有效,因为 onX
内联事件处理程序接收一个名为 event
的隐式类似参数的局部变量,这是一个新创建的 Event每个新事件的
对象。这将被传递给 eventFired
函数并被记住以供以后使用。
在旧版 IE 事件模型中,没有单独的事件对象,只有 window.event
属性,其中只有一个属性,它返回当前正在处理的事件的详细信息。当您在内联事件处理程序属性中引用 event
时,您会将该属性作为全局变量获取,而不是作为本地参数获取新生成的实例。它被传递给函数并被记住,但只记住对象,而不记住它的值。稍后,当重新使用该对象时,其属性反射(reflect)正在处理的新事件(如果有),而不是旧事件。
因此,请仅记住您想要保留的特定属性值,而不是 event
对象。我还会避免使用内联事件处理程序属性,因为它们有很多陷阱。
<input type="button" id="fire-now" value="Fire now" />
<input type="button" id="fire-delay" value="Fire delay" />
<script type="text/javascript">
document.getElementById('fire-now').onclick= function(e) {
e= e || window.event;
alert(event.button);
};
document.getElementById('fire-delay').onclick= function(e) {
e= e || window.event;
var button= e.button;
setTimeout(function() {
alert(button);
}, 1000);
};
</script>
请注意,这并不是跨浏览器担忧的结束,因为 IE<9 的 button
属性具有 different values符合标准MouseEvent buttons !
关于javascript - IE settimeout丢失事件变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6220187/