简体   繁体   中英

Issues with Javascript letter scrambling / conflicting scripts

I am very new to Javascript and am writing a little webapp that generates random strings (used for visualisation, doesn't need to be perfectly random) and then resolves these strings to a randomly selected given string.

The site consists of three divs, which each generate a random string. On pageload, the divs display 20 hyphens as visual placeholders. Within each div, the hyphens then get replaced with random characters one by one.

As soon as the user presses a button, the characters get scrambled again for 100 iterations (100 times a random character in the array gets changed to another random character). After 100 iterations, a random final value is selected from an array and the random string in the div gets replaced with that selected value. This replacing happens one character at a time, the order in which these characters are replaced is random (eg the second character might be replaced first, then the last, then the first etc.).

Every time a character gets replaced, it is supposed to wait a given time before continuing execution (using setTimeout).

This more or less works fine, however, some characters are still wrong in the end. Sometimes it works, sometimes there are some random leftovers.

What I have noticed:

  • When having a larger waiting period while replacing with the final value, then I have less issues. On the other hand, when the waiting period is shorter, then a lot more characters are wrong
  • When the loopRealOutput iterates, i seems to get reset to 0 (using Chrome debugger)

I have absolutely no idea where to even begin resolving this issue. I can't even figure out if the realOutput doesn't get written all the way or if it gets overwritten again. Because the arrays with the values get pulled correctly (I'll add some console.logs to show).

So my question:

What is causing this issue and how can I resolve it?

Thanks for your help, let me know if you need anything else!

 const values = { form: ["Value 1", "Value 2", "Value 3"], modus: ["Test1", "Test2", "Test3", "Test4", "Test5", "Test6"], inhalt: [ "Input-1", "Input-2", "Input-3", "Input-4", "Input-5", "Input-6", ], }; const placeholderLength = 20; let valueForm = [], valueModus = [], valueInhalt = [], placeholder = []; const outputForm = document.getElementById("outputForm"); const outputModus = document.getElementById("outputModus"); const outputInhalt = document.getElementById("outputInhalt"); const randomCharacter = () => { const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 "; return characters.charAt(Math.floor(Math.random() * characters.length)); }; const randomNumber = (max) => { return Math.floor(Math.random() * max); }; const initialValues = (value, destination) => { let i = 0; const loop = () => { setTimeout(() => { value[i] = randomCharacter(); let valueJoined = value.join(""); destination.innerHTML = valueJoined; i++; if (i < placeholderLength) { loop(); } else {} }, 100); }; loop(); }; const main = () => { for (let i = 0; i < placeholderLength; i++) { placeholder.push("-"); } valueForm = placeholder.slice(); valueModus = placeholder.slice(); valueInhalt = placeholder.slice(); initialValues(valueForm, outputForm); initialValues(valueModus, outputModus); initialValues(valueInhalt, outputInhalt); }; const scramble = (value, destination, i) => { setTimeout(() => { value[i] = randomCharacter(); let valueJoined = value.join(""); destination.innerHTML = valueJoined; }, 100); }; const shuffledArray = (len) => { let shuffledArray = []; let val = 0; while (shuffledArray.length < len) { shuffledArray.push(val); val++; } return shuffledArray.sort(() => 0.5 - Math.random()); }; const realOutput = (value, output, valueList) => { const realText = valueList[randomNumber(valueList.length)]; console.log(realText); const realArray = Array.from(realText); while (realArray.length < 20) { realArray.push("-"); } let orderArray = shuffledArray(realArray.length); let i = 0; const loopRealOutput = () => { setTimeout(() => { value[orderArray[i]] = realArray[orderArray[i]]; let valueJoined = value.join(""); output.innerHTML = valueJoined; i++; if (i < value.length) { loopRealOutput(); } else {} }, 20); }; loopRealOutput(); }; //------------------------------------------ // THIS GETS CALLED WHEN PRESSING THE BUTTON //------------------------------------------ const randomize = () => { let counter = 0; const iterations = 200; const loop = () => { setTimeout(() => { scramble(valueForm, outputForm, randomNumber(valueForm.length)); scramble(valueModus, outputModus, randomNumber(valueModus.length)); scramble(valueInhalt, outputInhalt, randomNumber(valueInhalt.length)); counter++; if (counter < iterations) { loop(); } else { realOutput(valueForm, outputForm, values.form); realOutput(valueModus, outputModus, values.modus); realOutput(valueInhalt, outputInhalt, values.inhalt); return; } }, 5); }; loop(); }; main();
 body {}.output { font-family: monospace; letter-spacing: 1px; font-size: 1.5em; }
 <,DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width. initial-scale=1.0" /> <link rel="stylesheet" href="main.css" /> <title>Document</title> </head> <body> <div class="flex-container"></div> <h2>Value 1</h2> <div id="outputForm" class="output"></div> <h2>Value 2</h2> <div id="outputModus" class="output"></div> <h2>Value 3</h2> <div id="outputInhalt" class="output"></div> <!-- <div>placeholder</div> --> <button onclick="randomize()">Button</button> </body> <script src="app.js"></script> </html>

I just added another setTimeout (inside randomize, to pause before calling realOutput), which does seem to resolve this issue. However - this really seems like a workaround to me and if anybody has an idea on how to actually fix this, your input would be much appreciated!

 const values = { form: ["Value 1", "Value 2", "Value 3"], modus: ["Test1", "Test2", "Test3", "Test4", "Test5", "Test6"], inhalt: [ "Input-1", "Input-2", "Input-3", "Input-4", "Input-5", "Input-6", ], }; const placeholderLength = 20; let valueForm = [], valueModus = [], valueInhalt = [], placeholder = []; const outputForm = document.getElementById("outputForm"); const outputModus = document.getElementById("outputModus"); const outputInhalt = document.getElementById("outputInhalt"); const randomCharacter = () => { const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 "; return characters.charAt(Math.floor(Math.random() * characters.length)); }; const randomNumber = (max) => { return Math.floor(Math.random() * max); }; const initialValues = (value, destination) => { let i = 0; const loop = () => { setTimeout(() => { value[i] = randomCharacter(); let valueJoined = value.join(""); destination.innerHTML = valueJoined; i++; if (i < placeholderLength) { loop(); } else {} }, 100); }; loop(); }; const main = () => { for (let i = 0; i < placeholderLength; i++) { placeholder.push("-"); } valueForm = placeholder.slice(); valueModus = placeholder.slice(); valueInhalt = placeholder.slice(); initialValues(valueForm, outputForm); initialValues(valueModus, outputModus); initialValues(valueInhalt, outputInhalt); }; const scramble = (value, destination, i) => { setTimeout(() => { value[i] = randomCharacter(); let valueJoined = value.join(""); destination.innerHTML = valueJoined; }, 100); }; const shuffledArray = (len) => { let shuffledArray = []; let val = 0; while (shuffledArray.length < len) { shuffledArray.push(val); val++; } return shuffledArray.sort(() => 0.5 - Math.random()); }; const realOutput = (value, output, valueList) => { const realText = valueList[randomNumber(valueList.length)]; console.log(realText); const realArray = Array.from(realText); while (realArray.length < 20) { realArray.push("-"); } let orderArray = shuffledArray(realArray.length); let i = 0; const loopRealOutput = () => { setTimeout(() => { value[orderArray[i]] = realArray[orderArray[i]]; let valueJoined = value.join(""); output.innerHTML = valueJoined; i++; if (i < value.length) { loopRealOutput(); } else {} }, 20); }; loopRealOutput(); }; //------------------------------------------ // THIS GETS CALLED WHEN PRESSING THE BUTTON //------------------------------------------ const randomize = () => { let counter = 0; const iterations = 200; const loop = () => { setTimeout(() => { scramble(valueForm, outputForm, randomNumber(valueForm.length)); scramble(valueModus, outputModus, randomNumber(valueModus.length)); scramble(valueInhalt, outputInhalt, randomNumber(valueInhalt.length)); counter++; if (counter < iterations) { loop(); } else { setTimeout(() => { realOutput(valueForm, outputForm, values.form); realOutput(valueModus, outputModus, values.modus); realOutput(valueInhalt, outputInhalt, values.inhalt); return; }, 100); } }, 5); }; loop(); }; main();
 body {}.output { font-family: monospace; letter-spacing: 1px; font-size: 1.5em; }
 <,DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width. initial-scale=1.0" /> <link rel="stylesheet" href="main.css" /> <title>Document</title> </head> <body> <div class="flex-container"></div> <h2>Value 1</h2> <div id="outputForm" class="output"></div> <h2>Value 2</h2> <div id="outputModus" class="output"></div> <h2>Value 3</h2> <div id="outputInhalt" class="output"></div> <!-- <div>placeholder</div> --> <button onclick="randomize()">Button</button> </body> <script src="app.js"></script> </html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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