I have a simple sigma calculator that works very well, except a little hiccup when the user requests a large span of n. Below is an image: Image of sigma calculator

As shown in the image, the function is going to take a while to finish calculating the sum (I do it with a loop). When the user presses Enter in any of the three inputs or clicks on the arrow the calculation is kicked off by calling a function to set the background image of the output field, then the calculation function itself followed by a function that removes the background image.
My problem is that the page just completely hangs while calculating. I've also tried window.requestAnimationFrame(()=>{}) in the loop but that didn't have any effect on the hanging of the whole page. When I changed the callback to (x)=>{console.log(x);} it would spam the same float number over and over again in the console.
Running the function rechenanimation(1) would correctly put a loading animation into the right of the output field and calling the same function with 0 would correctly remove it again.

以下是该计算器的精简版本的代码片段:

function sigmaCalc(start, end, exp){
    var sum = 0;
    for (var n=start; n<=end; n++) {
        sum+=(exp.replace('^','**').match(/^[\d\+\-\*\/\(\)n]+$/)) ? eval(exp.replace('n',n)) : NaN; 
    }
    return sum;
}
// sigmaCalc(start=1, end=10, exp='2*n+1') → 120

function copyresult() {
    const result = document.querySelector('form#sigmarechner label[for=r] input').value;
    navigator.clipboard.writeText(result);
    alert(`Kopiert:\n${result}`);
}

function copyall() {
    const mathml = `<math display="block"><mrow><munderover><mo>&sum;</mo><mrow><mi>n</mi><mo>=</mo><mn>${document.querySelector('form#sigmarechner label[for=n] input').value}</mn></mrow><mrow><mi>m</mi><mo>=</mo><mn>${document.querySelector('form#sigmarechner label[for=m] input').value}</mn></mrow></munderover>${document.querySelector('form#sigmarechner label[for=f] input').value} = ${document.querySelector('form#sigmarechner label[for=r] input').value}</mrow></math>`;
    navigator.clipboard.writeText(mathml);
    alert(`Kopiert:\n${mathml}`);
}

function rechenanimation(an) {
    const style = document.querySelector('form#sigmarechner input#r').style;
    // background-repeat:no-repeat;background-image:url("/assets/pixel-loader/pixel-loader_56.gif");background-size:contain;background-position:right;
    style.backgroundImage = (an) ? 'url(/assets/pixel-loader/pixel-loader_56.gif)' : '';
    style.backgroundRepeat = (an) ? 'no-repeat' : '';
    style.backgroundSize = (an) ? 'contain' : '';
    style.backgroundPosition = (an) ? 'right' : '';
}
input {
    background-color: green;
}
<form id="sigmarechner" onsubmit="event.preventDefault();rechenanimation(true);this.querySelector('input[id=r]').value=sigmaCalc(this.querySelector('input[name=n]').value,this.querySelector('input[name=m]').value,this.querySelector('input[name=f]').value);/*this.querySelector('input[id=r]').focus();*/this.querySelector('input[id=r]').select();rechenanimation(false);" oninput="this.querySelector('input[id=r]').value=''" method="get" action="">
    <label for="m">m=<input name="m" id="m" type="number" placeholder="Endwert" required tabindex="2" value="100000"></label>
    <label for="n">n=<input name="n" id="n" type="number" oninput="const elmnt=document.querySelector('input[name=m]');elmnt.min=(this.value)?this.value:''" placeholder="Startwert" required tabindex="1" autofocus value="1"></label>
    <label for="f">&sum;<input name="f" id="f" type="text" placeholder="Formel" pattern="^[\d\+\-\*\/\(\)n\^]+$" required tabindex="3" value="2*n+1"></label>
    <label for="r"><span id="ergebnispfeil" onclick="document.querySelector('form#sigmarechner input[type=submit]').click();"> → </span><input id="r" type="text" readonly placeholder="Ergebnis"></label>
    <input type="submit" value="→" hidden>
    <button id="kopieren" onclick="event.preventDefault();copyresult();" oncontextmenu="event.preventDefault();copyall();" title="[Linksklick]: Ergebnis kopieren
[Rechtsklick]: MathML kopieren">?<!-- U+1F4CB --> Kopieren</button>
</form>
<br>
<a style="color:blue" href="https://www.lampe2020.de/extras/sigmarechner?m=100000&n=1&f=2*n%2B1" onclick="/*event.preventDefault(); */window.open('https://www.lampe2020.de/extras/sigmarechner?m=100000&n=1&f=2*n%2B1', '_blank', 'popup');">The original page is at Lampe2020.de/extras/sigmarechner</a>

推荐答案

Using Web Workers

Web Worker是Web内容运行脚本的一种简单方法 后台线程.辅助线程可以执行任务,而无需 干扰用户界面.

Javascript相关问答推荐

如何在Node.js中减go 两个日期和时间?

我无法使用tailwind-css和reactJS修改图像的位置

设置默认值后动态更新japbox或调色板

调用SEARCH函数后,程序不会结束

一次仅播放一个音频

我不知道为什么我的JavaScript没有验证我的表单

使用javascript将Plotly Expandable Sparkline转换为HighCharter Plot在bslib卡中

空的结果抓取网站与Fetch和Cheerio

这个值总是返回未定义的-Reaction

连接到游戏的玩家不会在浏览器在线游戏中呈现

查询参数未在我的Next.js应用路由接口中定义

使用VUE和SCSS的数字滚动动画(&;内容生成)

回溯替代方式

AJAX POST在控制器中返回空(ASP.NET MVC)

与svg相反;S getPointAtLength(D)-我想要getLengthAtPoint(x,y)

未捕获的运行时错误:调度程序为空

如何使用<;Link>;执行与JS Reaction中的";window.Location=/GameOverDied;";类似的操作?

如何组合Multer上传?

Node.js错误: node 不可单击或不是元素

为什么我不能使用其同级元素调用和更新子元素?