IE settimeout丢失事件变量

时间:2011-06-02 20:45:56

标签: javascript internet-explorer-8 settimeout

这似乎在Firefox中工作得很好但是,在IE8中(可能在其他版本的IE中工作),我遇到了丢失事件变量的问题。

有一个事件(mousedown)调用一个存储参数集的函数。其中一个参数是事件本身。调用的函数将参数存储在全局变量中,以便settimeout中调用的函数可以访问它们。

执行后,set timeout调用的函数不再能访问事件变量中的属性。它仍然被识别为事件对象,但所有属性都被重置。

我尝试过使用函数引用,使用全局函数的匿名函数,并将它们作为参数传递,但似乎没有任何工作。有人有什么想法吗?

我知道这有点复杂所以我设置了一个简单的例子来说明我的问题: http://jsfiddle.net/fd8sk/

当您单击“立即启动”(不使用settimeout)时,您会看到按钮单击是一个数字。当您点击“火灾延迟”时,该按钮现在为“未知”。

这是一个非常通用的函数,它有很多参数并不总是使用,所以我希望避免对此进行重大的重构。在我的实例中,作为我的问题案例中的事件的参数将不是其他场景中的事件。

2 个答案:

答案 0 :(得分:4)

onmousedown="eventFired(event);"

在IE< 9的事件模型中与在其他浏览器中的事件模型略有不同。

在大多数浏览器中,上述工作原理是因为onX内联事件处理程序接收一个名为event的隐式参数式局部变量,它是每个新事件的新建Event对象。这将传递给eventFired函数并记住以供以后使用。

在legacy-IE事件模型中,没有单独的事件对象,只有window.event属性,它只有一个属性,一个返回正在处理的当前事件的详细信息。当您在内联事件处理程序属性中引用event时,您将该属性作为全局变量获取,而不是将新生成的实例作为本地参数。这将传递给函数并记住,但只记住对象而不记住它的值。稍后,当对象被重用时,其属性反映了正在处理的新事件(如果有),而不是旧事件。

因此,请记住您只想保留的特定属性值而不是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&lt; 9的button媒体资源different values已标MouseEvent buttons

答案 1 :(得分:0)

IE不会传递事件,您必须查看window.event。另外,您无法在IE中存储对事件对象的引用。您需要复制要使用它的属性并将其存储在新对象中。