简体   繁体   English

JavaScript 慢 DOM 更新

[英]JavaScript Slow DOM Update

I am currently working on an electron project and in a part the project I want to recursively find files in a directory and show each filename to user like how winrar does.我目前正在处理一个电子项目,在该项目的一部分中,我想递归地在目录中查找文件,并像 winrar 那样向用户显示每个文件名。

You all know how winrar works while we archive or unarchive something, filenames shown rapidly and a progress bar goes forward.你们都知道 winrar 在我们存档或取消存档时是如何工作的,文件名会快速显示并且进度条会向前显示。 This is very similar to what I am trying to do.这与我正在尝试做的非常相似。 See image below.见下图。

样本1

Now the problem is, while electron scanning directory recursively it finds files one by one, then prints filename in console but not in the DOM.现在的问题是,当电子扫描目录递归时,它会一个一个地查找文件,然后在控制台中打印文件名而不是在 DOM 中。 This situation makes user to think program is not working if scanning takes long.如果扫描时间过长,这种情况会使用户认为程序不起作用。 At the end of scanning program show the last filename to user after all scanning operation is complete.在所有扫描操作完成后,扫描程序结束时向用户显示最后一个文件名。

For this reason I have wrote a sample code to update DOM rapidly in browser, I got the same issue what I came across in my electron project.出于这个原因,我编写了一个示例代码来在浏览器中快速更新 DOM,我遇到了与我在电子项目中遇到的相同问题。 How can I overcome this issue, I have never seen anything like that before and why this happens please explain.我怎样才能克服这个问题,我以前从未见过这样的事情,为什么会发生这种情况,请解释一下。

Sample code is here.示例代码在这里。 Increase number to 10000 and try in your browser for better understanding.将数字增加到 10000 并尝试在您的浏览器中更好地理解。

 var myBtn = document.getElementById('myBtn'); var myDiv = document.getElementById('myDiv'); myBtn.addEventListener('click', function() { for (var i = 0; i < 1000; i++) { myDiv.innerHTML = i; console.log(i); } });
 #myDiv { border: 1px solid black; padding: 30px; margin-bottom: 10px; } #myBtn { padding: 10px; }
 <div id="myDiv"></div> <button id="myBtn" type="button" name="button">Button</button>

In order to understand what's going on, you need to understand how the event loop works.为了了解发生了什么,您需要了解事件循环的工作原理。 Because JS is a single-threaded language, individual units of code (known as "tasks") take turns to execute, but one can never interrupt another.因为 JS 是一种单线程语言,各个代码单元(称为“任务”)轮流执行,但永远不能中断另一个。 That's why your code doesn't work.这就是为什么您的代码不起作用的原因。 The main thread is stuck on that loop and can't do anything else until it's finished.主线程卡在那个循环上,在它完成之前不能做任何其他事情。

You can use window.requestAnimationFrame() to animate the text, but you probably should show the file which is currently being processed, which is what WinRar does.您可以使用window.requestAnimationFrame()为文本设置动画,但您可能应该显示当前正在处理的文件,这正是 WinRar 所做的。

 const outDiv = document.getElementById("output"); // The each number is displayed. (lower = faster) const PERIOD = 50; // The limit. const MAX = 100; // The code is written like this so it always runs // at the same speed. Never increment `i` in the // handler! let startTime = performance.now(); function handler(now) { const timeDiff = (now - startTime), i = Math.min(Math.floor(timeDiff / PERIOD), MAX); outDiv.innerText = i; if (i < MAX) { window.requestAnimationFrame(handler); } } handler(startTime);
 <div id="output"></div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM