【问题标题】:Javascript setTimeout and redirect - IE freezesJavascript setTimeout 和重定向 - IE 冻结
【发布时间】:2014-05-03 01:24:38
【问题描述】:

我的页面上有一个脚本处理会话超时,当会话到期时重定向客户端的用户。完整的代码稍微复杂一些,但我已将代码精简到导致我出现问题的原因:

<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(唯一的主要区别是这将是 localhost 地址),仍然不起作用。

【问题讨论】:

  • 变量'redirectTimeout'是否声明在任何地方?由于它的工作奇怪尝试清除redirectTimeout。只是在黑暗中开枪;D。
  • 对不起,redirectTimeout 应该在那里。
  • window.location.replace("Test2.aspx");window.navigate("Test2.aspx");self.location=Test2.aspx 你试过这些,这些也冻结了吗?
  • @03Usr - 这三个都没有对结果产生影响。
  • @Paddy - 我现在在 IE10 中遇到同样的问题。你最终找到解决方案了吗?下面标记的答案对我不起作用。在计算机被锁定时,JavaScript 事件似乎仍在按时执行....但是窗口还没有重新绘制。我发现的另一件事是,如果您在冻结的屏幕上用鼠标快速单击大约 3-5 次,它几乎会立即重新绘制……而不是等待 10 秒。对我来说,它确实已经重定向到新的 URL.... 只是没有重新绘制屏幕来显示这个。

标签: javascript internet-explorer


【解决方案1】:

我遇到了相同类型的问题,我创建了一个不同的问题,以便我可以专注于我认为是问题的核心。 (电脑处于锁屏状态时,IE 不会重新绘制。)

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

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

    • 已经考虑过做这样的事情,但仍然想弄清楚为什么会发生这种情况。想确保我没有遗漏一些邪恶的东西。
    • 经过一些测试,我很确定这只是IE没有执行渲染;如果您打开页面,然后单击另一个窗口(因此 IE 失去焦点),然后锁定屏幕,并在 10 多秒后解锁,IE 仍将冻结在您锁定屏幕时显示的秒数。但是,该网址将被更新。再次关注 IE 窗口,将更新视图,并带您到重定向页面。换句话说,好像你已经被重定向了,但它还不可见。
    • 确实 - 您可以在浏览器栏中看到新的 URL,但它还没有呈现,而且它需要很长时间才能启动。
    【解决方案3】:

    我这里没有 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 并对其进行了一些修改。

    我希望这会有所帮助。

    【讨论】:

    • 确实这是另一种方法,我自己也看过类似的东西。但是,这确实意味着窗口将继续显示为“打开”,直到单击它进行重定向时,这并不理想。
    • 感谢您的示例 - 刚刚有机会查看它 - 似乎有效。将看看调整我的代码。仍然有点好奇为什么会发生这种情况,但是嘿。
    • 我不知道为什么,所以我最好不要猜测。对于页面在后台看起来活跃的问题,您仍然可以显示一些有关重定向的警告或半透明层,以在窗口未聚焦时可视化会话超时。只要不发生重定向,您就应该在性能方面保持良好。
    • @Torsten Walter - 我在 IE10 中测试了您的示例页面,但它不起作用。一旦我锁定屏幕,页面上呈现的倒计时就会冻结。步骤:等待倒计时开始,锁屏,等待20秒,解锁屏幕。窗口没有重绘....最近的消息仍然说“还剩 15 秒”....然后我在屏幕上快速单击鼠标大约 3-5 次。这会导致屏幕解冻,并立即立即显示剩余的“剩余 X 秒”消息。似乎单击一次不会这样做...必须是一系列快速连续的鼠标单击。
    • 好像api变了。在 IE 10 中,现在可以使用page visibility api。该示例必须更新。
    猜你喜欢
    • 2016-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-11
    • 1970-01-01
    • 2013-01-25
    • 1970-01-01
    • 2021-04-11
    相关资源
    最近更新 更多