如何在长时间运行的事件中更新页面元素

How do update a page element while inside a long running event?

本文关键字:更新 元素 事件 长时间 运行      更新时间:2023-09-26

我有一个长时间运行的方法——我想向用户表明一个操作正在进行。这不是ajax调用,所以我不能使用过去使用的常见模式,例如在ajax事件之前显示一个旋转器,然后在成功时隐藏它。

在我的例子中——我没有进行ajax调用,而是进行一些非常繁重的DOM操作。

我在jsFiddle.net上有一个测试示例——我很想学习如何捕获事件。目前,我的"wait-message"div在我的操作完成的同一时间更新,这太迟了:(

完整的示例代码在这里:http://jsfiddle.net/rsturim/97hrs/6/

Javascript (jQuery)

$(document).ready(function() {
    $("#link-action").click(function(e) {
        $("#wait-message").text("starting ...");
        var count = longRunningMethod(1000000000);
        $("#result").text(count);
        $("#wait-message").text("completed.");
    });

    var longRunningMethod = function(countUpTo) {
        var i = 0;
        while (i <= countUpTo) {
            i++;
        }
        return i;
    };
});
HTML:

<div id="wait-message">
    push button please 
</div>   
<hr />
<button id="link-action">Run Operation</button>
<hr />
<h1>Results:</h1>
<div id="result"> </div>   

这是一个解决方案。我不确定它是否适用于所有浏览器,你可能想在几个浏览器中测试一下,但我认为它可以:

$(document).ready(function() {
    $("#link-action").click(function(e) {
        $("#wait-message").text("starting ...");
        // Stuff to do after a render
        setTimeout(function(){
            var count = longRunningMethod(1000000000);
            $("#result").text(count);
            $("#wait-message").text("completed.");
        }, 0);
    });

    var longRunningMethod = function(countUpTo) {
        var i = 0;
        while (i <= countUpTo) {
            i++;
        }
        return i;
    };
});

基本上,浏览器不会呈现任何更改,直到脚本完成执行。它允许你做这样的事情:

  • 隐藏所有类的div
  • 显示其中一个div

在一行中,浏览器永远不会将显示的div渲染为隐藏,所以你不会看到奇怪的闪烁或在页面上移动的东西。

像我一样使用setTimeout,匿名点击处理程序将完成执行,浏览器将重新渲染,setTimeout中的匿名函数将运行(在渲染之后立即运行,因为没有实际的延迟)。

使用setTimeout或setInterval代替while循环;像15ms这样的亚秒级延迟应该足以防止窗口冻结/UI锁定。