javascript - IE settimeout丢失事件变量

标签 javascript internet-explorer-8 settimeout

这似乎在 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/

相关文章:

javascript - 当用户遍历 map 时,如何根据当前 map Canvas 绘制标记

javascript - 无法在 JavaScript 中访问 JSON 数组的值

ruby-on-rails - 有没有办法用元标记做 If IE8 检查?

javascript - 权限被拒绝调用 javascript 函数

javascript - 如何在 C++ 中使用 JavaScript

jquery - setTimeOut 使用 JQuery 函数 .live()

javascript - 将 window.location.href 与 Jquery Mobile 和 RequireJS 一起使用时如何避免出现空白页?

javascript - 在网站的 javascript 完成页面构建后,如何运行 Chrome 扩展内容脚本?

javascript - 如何在 setTimeout() 中设置构造函数对象的值?

javascript - setTimeout 在异步代码中不起作用