jquery, while loop running in the background, simultaneous while loops - javascript

1) How make that while loop would run in background, and the webpage would respond to user clicks despite while loop.
If I start the characters generating while loop, I am not able to input the data to the "input", because the generating loop occupies all resources. Actually, whenever I click "start", I am getting the message that the webpage is not responding asking if I want to stop it. After choosing "to stop", I see that the characters are generated. Nevertheless, it is very difficult to input the characters to the input field and to stop the program with "stop" trigger, and usually webpage crashes.
2) How to make several jquery while loops to run simultaneously, and additionally, webpage should be responsive and accessible to user.
<!DOCTYPE html>
<html>
<head>
<script src="theme/assets/js/jquery/jquery-2.2.3.min.js"></script>
</head>
<body>
<div id="Start"> <b> Start </b> </div>
<div id="Stop"> <b> Stop </b> </div>
<br><br> <div id="random"> </div>
<br><br> <input id="input" type="text" size="500">
<script>
// how to manage without global variables? how to pass variables to the function
var flag = false;
var charstr = "zxcvbnm,\.\/asdfghjkl;\'qwertyuiop[]\\`ąčęėįšųū90\-ž";
var charstrL = charstr.length;
$("#Start").click( function() {
$("#lesson").text("clicked Start");
flag =true;
$(this).val('flag');
while(flag){
setInterval(function() { // this code is executed every 500 milliseconds:
var rand = Math.random();
var num = Math.floor( ( Math.random() * (charstr.length -1) ) );
$("#lesson").text(charstr[num]);
}, 500);
}//while
}); // $("#Start").click( function() {
$("#Stop").click( function(){
flag=false;
$(this).val('flag');
alert('clicked Stop');
});
</script>
</body>
</html>

You can't make a while loop run in the background if it's doing DOM manipulation, because there's only one main UI thread in browser JavaScript.
You also probably don't want to, because this code:
while (flag) {
setInterval(function() { // this code is executed every 500 milliseconds:
var rand = Math.random();
var num = Math.floor( ( Math.random() * (charstr.length -1) ) );
$("#lesson").text(charstr[num]);
}, 500);
}
continuously adds additional timers to call that code every 500ms. In a very short period of time, your browser will become completely non-responsive.
Just set up setInterval, and have the code inside decide whether to run based on flag:
setInterval(function() { // this code is executed every 500 milliseconds:
if (flag) {
var rand = Math.random();
var num = Math.floor( ( Math.random() * (charstr.length -1) ) );
$("#lesson").text(charstr[num]);
}
}, 500);
You can have several of those, though if you have a lot of them you might consider having fewer and just having them do more than one thing each time.

This is a working example for a program prompting user to input characters utilizing setInterval function instead of while loop. The application is to improve the typing skills.
<!DOCTYPE html>
<html>
<head>
<script src="theme/assets/js/jquery/jquery-2.2.3.min.js"> </script>
</head>
<body>
<div id="Start"> <b> Start </b> </div>
<br><div id="lesson"> </div>
<input id="input" type="text" size="500">
<span id="Stop"> Stop </span>
<span id="Clear">
Clear </span>
<script>
// how to manage without global variables ? how to pass vaiables to the function
var flag = false;
var charstr = "zxcvbnm,\.\/asdfghjkl;\'qwertyuiop[]\\`ąčęėįšųū90\-ž";
var charstrL = charstr.length;
$("#Start").click( function() {
flag =true;
$(this).val('flag');
if(flag){
setInterval( function() { // this code is executed every 500 milliseconds:
if (flag) {
var rand = Math.random();
var num = Math.floor( ( Math.random() * (charstr.length -1) ) );
$("#lesson").text("\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0"+charstr[num]);
} //if (flag) {
}, 500);
} // if (flag)
}); // $("#Start").click( function() {
/*
// does not work, because creates infinite loops, each with 500ms waiting time.
// In miliseconds this accumulates to hours and thousands of loops generated usign while
while(flag){
setInterval(function() { // this code is executed every 500 milliseconds:
var rand = Math.random();
var num = Math.floor( ( Math.random() * (charstr.length -1) ) );
$("#lesson").text(charstr[num]);
}, 500);
}//while */
//
$("#Stop").click( function(){
flag=false;
$(this).val('flag');
});
$("#Clear").click( function(){
$("#input").val('');
$("#lesson").text(' ');
});
</script>
</body>
</html>

Related

How do I display a given random array element every two seconds until it is stopped?

I am trying to make a program that randomly displays one of four defined emojis given in an array when the button is clicked and switches every two seconds continues to do so until the stop button is clicked. Note that I have not finished the stop function yet as I cannot work out why my randomEmoji function is not displaying anything. Thanks in advance :).
var display = document.getElementById("emojiDisplay");
var emojiList = ["🥳", "🤩", "👾", "😵"];
function randomEmoji() {
emojiDisplay.innerHTML = emojiList[Math.floor(Math.random() *
emojiList.length)];
setInterval(function() {
document.getElementById("emojiDiplay").innerHTML = emojiList[i++];
if (i == emojiList.length) i = 0;
}, 2000);
}
function stop() {
}
<button onclick=randomEmoji()>Display random emoji</button>
<button onclick=stop()>Stop</button>
</br>
</br>
<div id="emojiDisplay">
</div>
Based on your idea and your code, I’ve updated it and let it work (the stop function works, too). You can check the below demo:
var display = document.getElementById("emojiDisplay");
var emojiList = [ "🥳", "🤩", "👾", "😵" ];
var i = 0;
var timer;
function randomEmoji() {
clearInterval(timer);
// Call show Emoji to let it shows instanly.
showEmoji();
// Put showEmoji function to let it repeats
timer = setInterval(function() {
showEmoji();
}, 2000);
}
function showEmoji() {
i = Math.floor(Math.random() * emojiList.length);
emojiDisplay.innerHTML = emojiList[i];
}
function stop() {
// clear interval timer to let it stops
clearInterval(timer);
}
<!DOCTYPE html>
<html>
<head>
<title>EmojiRandomiser</title>
</head>
<body>
<button onclick=randomEmoji()>Display random emoji</button>
<button onclick=stop()>Stop</button>
<br>
<br>
<div id="emojiDisplay">
</div>
</body>
</html>

HTML page doesn't update while a javascript function running

Chrome, FF. Opera and probably others browser show only the 100000 number at end of process, but i want see displayed in sequence 1..2..3..4...100000.
This code doesn't work well:
<html>
<head>
</head>
<body>
<button type="button" onclick="showSequence();">Show the numbers one at a time!</button>
<p id="herethenumbers">00</p>
<script>
function showSequence() {
el = document.getElementById('herethenumbers');
for(var nn=0;nn<=100000;nn++){
el.innerHTML = nn;
}
}
</script>
</body>
</html>
window.setTimeout isn't possible using when you don't know the execution time of a given process and even changing the attributes of the main div object (visibility e.g.) does not work for me.
Thanks at all.
UPDATE
Here a partial solution.
Allows you to view the status of a long process, for now, unfortunately only the beginning and the end of the (single) process.
<html>
<head>
</head>
<body>
<button type="button" onclick="executeMultiLongProcess();">Launch and monitoring long processes!</button>
<p id="statusOfProcess"></p>
<script>
var el = document.getElementById('statusOfProcess');
function executeMultiLongProcess() {
processPart1();
}
function processPart1() {
el.innerHTML = "Start Part 1";
setTimeout(function(){
for(var nn=0;nn<=100000000;nn++){ //..
}
el.innerHTML = "End Part 1";
window.setTimeout(processPart2, 0);
},10);
}
function processPart2() {
el.innerHTML = "Start Part 2";
setTimeout(function(){
for(var nn=0;nn<=100000000;nn++){ //..
}
el.innerHTML = "End Part 2";
window.setTimeout(processPartN, 0);
},10);
}
function processPartN() {
el.innerHTML = "Start Part N";
setTimeout(function(){
for(var nn=0;nn<=100000000;nn++){ //..
}
el.innerHTML = "End Part N";
},10);
}
</script>
</body>
</html>
I want to suggest using window.requestAnimationFrame rather than setTimeout or setInterval as it allows you to wait for the browser to render changes and right after that, execute some code. So basically you can do:
window.requestAnimationFrame( () => {
el.innerHTML = nn;
} );
I changed your function to be recursive. This way I can call the function to render the next number inside the window.requestAnimationFrame callback. This is necessary, as we ought to wait for the browser to render the current number and just after that, instruct the browser to render the next one. Using window.requestAnimationFrame inside the for loop would not work.
el = document.getElementById( 'herethenumbers' );
function showSequence( nn=0 ) {
if( nn <= 100000 ) {
window.requestAnimationFrame( () => {
el.innerHTML = nn;
showSequence( nn + 1 );
} );
}
}
<button type="button" onclick="showSequence();">
Show the numbers one at a time!
</button>
<p id="herethenumbers">00</p>
Use window.setInterval:
function showSequence() {
var el = document.getElementById('herethenumbers');
var nn = 0;
var timerId = setInterval(countTo100, 80);
function countTo100(){
el.innerHTML = nn;
nn++;
if (nn>100) clearTimeout(timerId);
}
}
<button type="button" onclick="showSequence();">
Show the numbers one at a time!
</button>
<p id="herethenumbers">00</p>
Update
the scenario is a bit different. You have a javascriot process that starts and ends without interruptions, it can work several minutes in the meantime, inside it, must show on screen the status of its progress.
JavaScript is single-threaded in all modern browser implementations1. Virtually all existing (at least all non-trivial) javascript code would break if a browser's javascript engine were to run it asynchronously.
Consider using Web Workers, an explicit, standardized API for multi-threading javascript code.
Web Workers is a simple means for web content to run scripts in background threads. The worker thread can perform tasks without interfering with the user interface. In addition, they can perform I/O using XMLHttpRequest (although the responseXML and channel attributes are always null). Once created, a worker can send messages to the JavaScript code that created it by posting messages to an event handler specified by that code (and vice versa).
For more information, see MDN Web API Reference - Web Workers.
Sample code below using setTimeout, only counts up to 100 for the sample.
Might want to check out Difference between setTimeout with and without quotes and parentheses
And then there is also: 'setInterval' vs 'setTimeout'
var delayId = null, frameTime = 25, countTo = 100, el, nn = 0;
function increment(e) {
if (delayId) {
window.clearTimeout(delayId);
}
el.textContent = nn++;
if (nn <= countTo) {
delayId = window.setTimeout(increment,frameTime);
}
}
window.onload = function() {
el = document.getElementById('herethenumbers');
var b = document.getElementById('start');
b.addEventListener("click",increment,false);
}
<button type="button" id="start">Show the numbers one at a time!</button>
<p id="herethenumbers">00</p>
Using requestAnimationFrame as suggested by Jan-Luca Klees is the solution to my problem, here a simple example of use of requestAnimationFrame. Allows you to run one or more long-duration processes with the interaction with objects on screen (a popup for example or others), requestAnimationFrame tells the browser you want to run an animation and you want the browser to call a specific function to update a animation.
<html>
<head>
</head>
<body>
<button type="button" onclick="startProcesses();">Start long duration process!</button>
<p id="status">Waiting to start processes</p>
<script>
el = document.getElementById('status');
var current_process = 1;
var total_process = 2;
var startEnd = 'S';
function startProcesses() {
function step(timestamp) {
if(current_process==1 && startEnd=='E') res = process1();
if(current_process==2 && startEnd=='E') res = process2();
//..n processes
if(startEnd=='S') el.innerHTML = "Process #"+current_process+" started..";
if(startEnd=='E') el.innerHTML = "Process #"+current_process+" "+res;
if(startEnd=='S' || current_process<total_process) {
if(startEnd=='E') current_process++;
startEnd = (startEnd=='S'?'E':'S');
window.requestAnimationFrame(step);
}else{
el.innerHTML = "Process #"+current_process+" "+res;
}
}
window.requestAnimationFrame(step);
}
function process1() {
for(var nn=0;nn<=10000;nn++){
console.log(nn);
}
return "Success!"; //or Fail! if something went wrong
}
function process2() {
for(var nn=0;nn<=10000;nn++){
console.log(nn);
}
return "Success!"; //or Fail! if something went wrong
}
</script>
</body>
</html>

How can i add a div based on TIME using js or jquery?

I want to create a timer that will add or remove divs ( inline divs ) based on time function in Javascript or Jquery.
E.g With each second i want to add a div or remove a div.
Can i get some ideas on this?
<html>
<head>
<title>Testing</title>
<script>
var i = 0;
var myVar=setInterval(function () {myTimer()}, 1000);
function myTimer()
{
document.getElementById('Container').innerHTML += "<div id='"+i+"'>This is the Div with New ID 'i'</div>";
i++;
}
</script>
</head>
<body>
<div id='Container'>
</div>
</body>
</html>
This Should Create a DIV each second inside the Div with id 'Container'
Use setInterval.
var diff = 1000, // how long between adds in milliseconds
totalTime = 0, // how long we have run
maxTime = 1000*60*60*5, // how long we want to run
interval = setInterval(function() {
$(".parentDiv").append($("<div>new div</div>"));
totalTime += diff; // keep track of all of our time
if (totalTime >= maxTime) {
clearInterval(interval);
}
},diff);
Note that the time is in milliseconds.
And to get rid of it
clearInterval(interval);
Beware that it will keep running, and if any of your actions take too long or slow down, you could find yourself with quite the mess stumbling over each other.
You can make use of setTimeout(function, mili seconds)
var testTimer;
function timer()
{
// Do your stuff
testTimer = setTimeout("timer()",1000);
}
This will call your timer function every one second. and you can do your stuff in this function
To stop this timer function you can do
window.clearTimeout(testTimer);

Write sequence of random numbers in javascript to paragraph

Really a newbie question but I can't seem to find the answer. I need to have this html file show a bunch of random numbers, separated by 1 second intervals. For some reason (maybe obvious) it is only showing me the last one unless I have 1 alert after each random number generated. How can I correct this?
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
var randomnumber
var message
function placePossibleWinner()
{
randomnumber=Math.floor(Math.random()*11);
message="Teste ";
message=message.concat(randomnumber.toString());
document.getElementById("WINNER").innerHTML=message;
//alert(".")
}
</script>
</head>
<body>
<script type="text/javascript">
function runDraw()
{
var i=1
alert("start")
while (i<20)
{
setTimeout("placePossibleWinner()",1000)
i++
}
}
</script>
<h1>H Draw</h1>
<p id="WINNER">Draw</p>
<p></p>
<button onclick="runDraw()">Get me winner!</button>
</body>
</html>
Thanks in advance for any answers/comments.
The problem is all your setTimeouts are being triggered at the same time. Adding alerts pauses the JavaScript execution, so you see each number. Without that, after 1 second, all 19 setTimeouts run (one after another) and you just see one number (the screen is updated so fast, you just see one).
Try using setInterval instead.
function runDraw() {
var i = 1;
var interval = setInterval(function(){
if(i < 20){
placePossibleWinner();
i++;
}
else{
clearInterval(interval);
}
}, 1000);
}​
This will run the function once every second, until i is 20, then it will clear the interval.
I believe you want setInterval instead. using setTimeout in a loop will just queue up 20 calls immediately and they will all fire at once 1 second later. Also, you are setting the innerHTML of the p which will overwrite any previous text.
function placePossibleWinner() {
// add a var here, implicit global
var randomnumber=Math.floor(Math.random()*11);
// add a var here, implicit global
message="Teste " + randomnumber + '\n'; // new line
document.getElementById("WINNER").innerHTML += message; // concat, don't assign
}
function runDraw() {
var counter = 1;
var intervalID = setInterval(function () {
if (counter < 20) {
placePossibleWinner();
counter++;
} else {
clearInterval(intervalID);
}
}, 1000);
}
You are resetting your message in your functions and you are calling placePossibleWinner() the wrong way... you want to use setInterval. Below is a modification of your html/javascript
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
var randomnumber;
var message = "Teste ";
var timesCalled = 0;
var funtionPointer;
function placePossibleWinner()
{
timesCalled++;
randomnumber=Math.floor(Math.random()*11);
message=message.concat(randomnumber.toString());
document.getElementById("WINNER").innerHTML=message;
if (timesCalled > 20)
{
clearInterval(functionPointer);
}
}
</script>
</head>
<body>
<script type="text/javascript">
function runDraw()
{
var i=1
alert("start")
functionPointer = setInterval(placePossibleWinner,1000)
}
</script>
<h1>H Draw</h1>
<p id="WINNER">Draw</p>
<p></p>
<button onclick="runDraw()">Get me winner!</button>
</body>
</html>
To start with,
setTimeout("placePossibleWinner()",1000)
should be
setTimeout(placePossibleWinner,1000)
The parameter to setTimeput should be a reference to a function. See JavaScript,setTimeout

How do I implement press and hold button javascript?

I'm a complete novice, looking for instructions on implementing javascript. I am attempting to replace a YUI slider with buttons and a text field. I am trying to achieve buttons that, when held down, will continue to make the text field increase, preferably at a faster and faster rate. (http://www.blackbird502.com/white.htm)I have this in the java tag in the head:
function holdit(btn, action, start, speedup) {
var t;
var repeat = function () {
action();
t = setTimeout(repeat, start);
start = start / speedup;
}
btn.mousedown = function() {
repeat();
}
btn.mouseup = function () {
clearTimeout(t);
}
/* to use */
holdit(btn, function () { }, 1000, 2);
/* x..1000ms..x..500ms..x..250ms..x */
I have no clue how to implement the press and hold into the following in the body:
<form><input type=button value="UP" class="btn" onClick="javascript:this.form.amount.value++;"><br /><input type=text name=amount value=5 class="text"><br /> <input type=button value="DOWN" class="btn" onClick="javascript:this.form.amount.value--;" ></form>
Is it possible? Thanks.
This code should do everything you're looking for; it's based very loosely on tj111's example. I tried to make it as reusable as possible, and it doesn't need JavaScript mixed in with the HTML.
You do need to add IDs to the buttons (btnUP and btnDOWN) and text field (amount). You can change these IDs in the window.onload statement.
// This function creates a closure and puts a mousedown handler on the element specified in the "button" parameter.
function makeButtonIncrement(button, action, target, initialDelay, multiplier){
var holdTimer, changeValue, timerIsRunning = false, delay = initialDelay;
changeValue = function(){
if(action == "add" && target.value < 1000)
target.value++;
else if(action == "subtract" && target.value > 0)
target.value--;
holdTimer = setTimeout(changeValue, delay);
if(delay > 20) delay = delay * multiplier;
if(!timerIsRunning){
// When the function is first called, it puts an onmouseup handler on the whole document
// that stops the process when the mouse is released. This is important if the user moves
// the cursor off of the button.
document.onmouseup = function(){
clearTimeout(holdTimer);
document.onmouseup = null;
timerIsRunning = false;
delay = initialDelay;
}
timerIsRunning = true;
}
}
button.onmousedown = changeValue;
}
//should only be called after the window/DOM has been loaded
window.onload = function() {
makeButtonIncrement(document.getElementById('btnUP'), "add", document.getElementById('amount'), 500, 0.7);
makeButtonIncrement(document.getElementById('btnDOWN'), "subtract", document.getElementById('amount'), 500, 0.7);
}
This is kind of quick and dirty, but it should give you a start. Basically you want to set up a few initial "constants" that you can play with to get the desired behavior. The initial time between increments is 1000 ms, and on each iteration if become 90% of that (1000, 990, 891, ... 100) and stops getting smaller at 100 ms. You can tweak this factor to get faster or slower acceleration. The rest I believe is pretty close to what I think you were going for. It seems like you were just missing the event assignments. In the window.onload you'll see that i assign the onmouseup, and onmousedown events to functions that just call the increment() or decrement() functions with your initial timeout, or the ClearTimeout() function to stop the counter.
EDIT: I changed this slightly to fix the bug. Now if you move your mouse pointer off the button and release it will stop the counter.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
<title><!-- Insert your title here --></title>
<script>
// Fake Constants
var INITIAL_TIME = 1000;
var ACCELERATION = .9;
var MIN_TIME = 100;
// create global variables to hold DOM objects, and timer
var up = null,
down = null,
count = null,
timer = null;
// Increment the counter
function increment (time) {
// decrease timeout by our acceleration factor, unless it's at the minimum
time = (time * ACCELERATION > MIN_TIME) ? (time * ACCELERATION) : MIN_TIME;
count.value ++ ;
// set the timeout for the next round, and pass in the new smaller timeout
timer = setTimeout(
function () {
increment(time);
}, time);
}
// Same as increment only subtracts one instead of adding.
// -- could easily make one function and pass an pos/neg factor instead
function decrement (time) {
time = time * ACCELERATION > MIN_TIME ? (time * ACCELERATION) : MIN_TIME;
count.value --;
timer = setTimeout(
function () {
decrement(time);
}, time);
}
// Initialize the page after all the forms load
window.onload = function () {
// initialization function
// assign DOM objects to our vars for ease of use.
up = document.getElementById('up_btn');
down = document.getElementById('dwn_btn');
count = document.getElementById('count');
// create event handlers for mouse up and down
up.onmousedown = function () {
increment(INITIAL_TIME);
}
down.onmousedown = function () {
decrement(INITIAL_TIME);
}
document.onmouseup = function () {
clearTimeout(timer);
}
}
</script>
</head>
<body>
<!-- Insert your content here -->
<form name="the_form">
<input type="button" value="Up" id="up_btn" /><br />
<input type="button" value="Down" id="dwn_btn" /></br>
<br />
Count:
<input type="text" value="0" id="count" />
</form>
</body>
</html>
The easiest method would be to just add an ID to each of the buttons, then use those to retrieve the elements and add the events.
//should only be called after the window/DOM has been loaded
window.onload = function() {
//the buttons
var btnUP = document.getElementById('btnUP');
var btnDOWN = document.getElementById('btnDOWN');
//the amount
var amount = document.getElementById('amount');
//actions to occur onclick
var upClick = function() {
amount.value++;
}
var downClick = function() {
amount.value--;
}
//assign the actions here
holdit(btnUP, upClick, 1000, 2);
holdit(btnDOWN, downClick, 1000, 2);
}
<form>
<input type=button value="UP" class="btn" id='btnUP'>
<br />
<input type=text name=amount value=5 class="text" id='amount'>
<br />
<input type=button value="DOWN" class="btn" id='btnDOWN'>
</form>
One aspect not to be overlooked is that you're hooking into the onclick event - which happens on a complete click (Mouse key down and key up). It sounds like you would want to listen for another distinct event, http://www.w3schools.com/jsref/jsref_onmousedown.asp'>onMouseDown . I think if you were to then implement some of the other timer based solutions, already given you would get the functionality you're asking for.
Good luck!

Categories