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:
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.
Below is a shrunk-down version of the calculator as a code snippet:
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>∑</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">∑<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>
Web Workers are a simple means for web content to run scripts in background threads. The worker thread can perform tasks without interfering with the user interface.