1

我的 Javascript 代码中有一些函数可以执行长时间的操作,例如将各种图像绘制到画布上。在执行这些功能时,我不希望用户能够访问 UI 上的按钮,因此我在所有内容上放置了一个大的模态 div 以在过程发生时掩盖按钮。然而,我很快意识到,由于代码是连续的,UI 永远没有机会更新,而且模态 div 从未真正出现,因为它在过程结束时被删除。

我的问题是,在这种情况下真的有必要掩盖 UI 吗?如果用户在执行操作时确实按下了另一个按钮,新进程是否会等到前一个进程完成后再开始?或者,也许由于模态 UI 在他们单击 UI 时应该已启动,因此模态将阻止新进程启动。另一种方法是,我可以在将模态 div 设置好之后直接设置一个超时时间,让 UI 有时间在开始该过程之前进行更新,但我不确定这是否有必要。

4

4 回答 4

1

如有疑问,请自行控制任务。当您开始“单一类型”操作时 - 提出一些标志,表明它正在进行中。如果您收到来自某个 UI 元素的消息,将再次启动此任务return。完成后,删除标志。

于 2012-05-01T22:46:42.963 回答
1

是的,您需要封面 div,不,新进程不会等到前一个进程完成后再开始(除非您对它们进行了编码)。

强制重绘的一个简单技巧是使用setTimeout毫秒0。重新布局应尽快进行。

于 2012-05-01T22:46:50.503 回答
1

由于引擎执行 javascript 的方式,您确实需要 div。如果您想阅读它,那将非常有趣-由 John Resig 撰写(如果我夸大其词,请原谅,呵呵)http://ejohn.org/blog/how-javascript-timers-work/。虽然是关于计时器和间隔,

如果您没有心情阅读,这里是摘要: 代码在同一个线程中执行,并且每当浏览器找到时间时,它就会暂停当前代码,并开始其他内容 - 执行本身不会停止 - 路径它的变化,暂时。我强烈建议您阅读完整的帖子。

于 2012-05-06T10:42:14.063 回答
1

正如@Parth 指出的那样,浏览器在单个线程中运行 javascript,因此,如果<div>不存在覆盖,UI 事件将被触发,但将保留在队列中,直到长时间运行的功能完成。但是,通常不会出现这种行为。如果要冻结 UI,只需保留<div>叠加层。

如果你想让浏览器有机会更新 UI(或允许用户取消处理),你必须将长时间运行的函数逻辑分解为各种函数调用,并使用window.setTimeout calls. 有几种方法可以实现这种模式,但我喜欢非递归封闭队列方法:

// this will block UI until all images are painted:
function paintAll(arImg) {
    for(var i=0; i<arImg.length; i++) paintSingle(arImg[i]);
}

// this will block UI only while each image is painted:
function paintAll(arImg) {
    // copy arImg to queue not to modify the input parameter
    var queue = arImg.slice(0);

    // apply the paint function to the first element, remove it from queue
    // and set the runner function to run again after 5 milliseconds
    // (this will allow the UI thread to run between each runner call)
    var runner = function() {
        // check any UI based condition to abort running:
        if(!checkUiBasedCondition()) return;

        if(!queue.length) return;
        paintSingle(queue.shift());
        window.setTimeout(runner, 5);
    }

    // call runner to initiate the processing
    runner();
}

https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/shift https://developer.mozilla.org/en/DOM/window.setTimeout

于 2012-05-07T11:37:41.700 回答