奇怪的Javascript行为:除非警报存在,否则忽略对Div的迭代更改

问题描述 投票:-1回答:1

我的代码包含一个冗长的For循环函数。接近循环的末尾是一个代码行,每次迭代时,都会增加用作状态栏的div的宽度。问题?状态栏的宽度仅在其上方有alert线时才会增加,以提醒我当前的循环计数器。当我评论alert,网页冻结,我听到很多电脑呼呼,最终我得到一个A网页正在减慢你的浏览器。你想干什么?浏览器消息。功能概述如下:

function processData(dataArr) {
// initialize the status bar
   var bar = document.createElement('div');
   bar.setAttribute("style","top:7px;left:125px;height:25px;width:400px");
   bar.id="StatusBar";
   document.body.appendChild(bar);
// now start the loop:
   for (var i=0;i<dataArr.length;i++) {
       // do a lot of string manipulation and parsing on dataArr[i]
// update the status bar every 50 iterations
       if (Math.ceil(i/50) == Math.floor(i/50)) {
           alert('Loop # '+(i+1)); // If this line is commented out, the status bar stops updating! 
       }
       bar.style.width = Math.round(((1+i)/dataArr.length)*400)+'px';
   }
// loop has finished last iteration, remove status bar
   document.body.removeChild(bar);
}

上面提到的alert行是其存在使得代码正常运行(数据被处理,状态栏随循环计数器增长)或网页冻结和获取网页正在减慢浏览器警告之间的差异的行。任何人都可以解释为什么看似良性的alert线会如此显着地改变这段代码的功能?

以下事实可能无关紧要,但万一它不是:在第二个函数中从onload: function()xmlhttpRequest代码块中调用上述函数。

更新:我刚刚找到another possibly-related stackoverflow question,这表明可能的根本原因是这个函数是从onloadxmlhttpRequest块中调用的。然而,这个问题的答案并没有提供我的问题的解决方案,并且问题没有涉及相同的主题(我使用的是用户脚本,并且页面加载似乎不是问题,因为我能够生成初始状态栏没有任何困难。除了在每个循环结束时更新状态栏外,循环内没有进行网页操作。)

第二次更新:已更正,以便正确关闭括号

javascript css for-loop userscripts tampermonkey
1个回答
-1
投票

当在for循环内时,一个看似无害的alert的存在允许CSS命令立即改变divdiv更改命令紧跟循环内的alert)每个循环增量,因为alert命令调用事件循环等待用户的响应(例如,点击警告框上的OK按钮)。在此等待期间,可以呈现DOM更改。如果没有alert命令(或某些替代方法,例如定时器以显式地导致实时DOM更改呈现),则在所有Javascript函数完成并且代码的执行已返回到浏览器的主事件循环之前,不会在网页上呈现更改。在我的例子中,代码中的这一点是当函数返回到调用它的第二个函数时,在onload:xmlhttpRequest块中。

这种行为的明确说明:虽然增加CSS宽度的div命令应该发生在每个for循环增量的末尾,但是div(用作状态栏)只是在每第50次循环迭代时生长,频率相同alert编码执行。为了满足状态栏显示数据处理进度的需要,我在我的代码中重新构建了工作流程:在调用上述函数之前,我没有等到第二个函数的xmlhttpRequest的所有数据块都被下载,我调用了上面的函数在下载时处理每个数据块。在xmlhttpRequest块中运行良好的状态栏现在表示数据的组合下载和处理。

© www.soinside.com 2019 - 2024. All rights reserved.