Javascript setTimeout和重定向 - IE冻结

时间:2012-07-20 11:18:12

标签: javascript internet-explorer

我的页面上有一个处理会话超时的脚本,在会话即将到期时重定向客户端的用户。完整的代码有点复杂,但我已经将代码缩减到了导致我这个问题的原因:

<head runat="server">
    <script src="javascript/jquery-1.7.2.min.js" type="text/javascript">
    </script>
    <script type="text/javascript">

        /*

            Please see document ready method at the bottom that sets
            up this code, calling CheckActivity() at intervals.

        */

        var warningInterval, redirectTimeout;
        var now = 1;

        function TimeoutRedirect() {
            window.location.href = "Test2.aspx";
        }

        //In this example this is a bit of a null op, but in real
        //code this will display a warning a minute or so prior to redirect.
        //This is required to recreate...
        function CheckActivity() {
            if (now > 4) {
                clearInterval(warningInterval);

                redirectTimeout = setTimeout(function () { 
                         TimeoutRedirect(); }, 5000);
            }

            //Some visual activity for testing purposes.
            $("#CheckActivityCount").text(now);
            now++;
        }


        $(document).ready(function () {
            warningInterval = setInterval(function () { 
                CheckActivity(); }, 1000);
        });
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <div id="CheckActivityCount">

        </div>
    </div>
    </form>
</body>

此代码按预期工作,在(大约)十秒后重定向。但是,如果间隔调用CheckActivity完成后(5秒后),我锁定我的屏幕,然后在重定向发生后再解锁(另外5秒),我的IE窗口中的URL已经转到'test2 .aspx',但窗口似乎已冻结(仍显示第一页)。

这最终不会冻结,但到达下一页需要10秒钟。

这似乎只发生在IE(我的机器上的IE9)上,并且在chrome和firefox(以及奇怪的IE6)中都很好。

(Test2.aspx是一个非常简单的页面,只包含文本'success'。)


注意如果我将重定向从test.aspx更改为http://www.google.com/,这似乎不是问题。但是,如果我将test2.aspx更改为绝对URL(唯一的主要区别是这将是本地主机地址)仍然无效。

3 个答案:

答案 0 :(得分:4)

我遇到了同样类型的问题,我创造了一个不同的问题,所以我可以专注于我认为是问题的核心。 (当计算机处于锁定屏幕时,IE不重新绘制。)

无论如何,我终于找到了解决这个问题的方法。您可以看到 my answer here 。基本上,您可以通过在自动注销目标页面中放置一些JavaScript来定期更新页面内容来修复您的问题....这将迫使IE重新绘制页面。

这样我可以在会话到期之前在当前页面上执行我想要的任何自动保存逻辑,然后将它们踢到自动注销页面。

答案 1 :(得分:1)

当你锁定屏幕时,听起来好像IE会进入某种形式的“暂停”模式,以避免在渲染时使用循环等等。也许你可以尝试将重定向链接到 onFocus - 窗口的事件,如下:

window.onfocus = function(){
    window.location.href = "Test2.aspx";
}
window.location.href = "Test2.aspx";

理论上,一旦重新获得焦点(即当您解锁屏幕时),这应该重定向页面。如果窗口已经有焦点,那么无论如何这都不应该有任何区别。

答案 2 :(得分:1)

我这里没有IE,所以我无法验证,但也许你可以推迟调用TimeoutRedirect直到窗口再次激活。

我已经构建了sample page来说明这一点。

原则很简单。在运行间隔和超时时,您可以在窗口变为非活动状态时重新设置变量,因为用户可以切换选项卡或锁定屏幕。超时结束后,检查窗口是否具有焦点。如果没有,请设置另一个变量以告诉focus处理程序运行会话结束函数。这应该有助于重定向。

sessionEnd: function() {
    this.sessionEnded = true;
    var windowEvents;
    if (!this.isInactive) {
        console.log("window active, sessionEnd called");
        alert("THE END");
        this.removeEvents();
        // window.location.href = "test.aspx";
    } else {
        console.log("window inactive, sessionEnd will be called again on focus");
    }

},

handleEvent: function(e) {
    // only do something if the window loses or gains focus
    if (this.eventBlurRegex.test(e.type)) {
        this.isInactive = true;
    } else if (this.eventFocusRegex.test(e.type)) {
        this.isInactive = false;
        if (this.sessionEnded === true) {
            this.sessionEnd.call(this);
        }
    }

},

对于不支持handleEvent功能的旧IE版本,我使用了CSS NInja处的polyfill并对其进行了一些修改。

我希望这会有所帮助。