Replacing previous number in JS/JQuery - javascript

I would like to add an effect that some websites now have i.e. coffees drank: and then number of coffees drank, gradually growing from 0 to N-1. This is my attempt, if I print i in the console in the first if statement , each number prints out. But, when in HTML it goes from 0-950 instantly with no numbers in between.
To sum make it up: I would like the number to increment on the page, each new number replacing its previous number.
for (i = 0; i < 950; i++) {
if ($("#counter").length) {
setTimeout(function() {
// body...
$("#counter").append('<p id = "counter">' + i + '</p>');
}, 2000);
console.log(i);
} else {
$(".coffee-drank").append('<p id = "counter">' + i + '</p>');
}
}

If I got your idea correctly, it can be done generally like this:
var start = -1, end = 950;
var countUp = function func() {
if(start >= end) return;
var elem = document.getElementById("counter");
elem.innerText = ++start;
setTimeout(func, 25);
}
countUp();
count up to 950:
<span id="counter">0</span>
UPDATE
In your case it might look like this (no need for a cycle at all):
var start = -1, end = 950;
var countUp = function func() {
if(start >= end) {
// the end is reached; start is equal to 950 now; do something useful and quit
$(".coffee-drank").append('<p id = "counter">' + start +'</p>');
return;
}
$("#counter").text(++start);
setTimeout(func, 25);
}
countUp();

Replace your for loop with this:
var speed = 16; // Lower is faster
increase(0, 950);
function increase(i, max){
if(i <= max){
if ($("#counter").length) {
$("#counter").html(i);
} else {
$(".coffee-drank").append('<p id = "counter">' + i + '</p>');
}
setTimeout(function(){
increase(++i, max);
}, speed);
}
}

Related

How to decrease audio volume while looping in javascript and jquery

I want to control audio volume by decreasing it while function loop, but my below code doesn't seems to work.
var count = 0;
var rotate= 5;
var saudio = $("#saudio").get(0);
function tryitnow(){
count++;
saudio.volume = parseInt(saudio.volume)- parseInt(0.1);
if (count != rotate) {
setTimeout(function() {
tryitnow()
}, 1000);
}
}
parseInt(0.1); will return 0 because it will round the float 0.1 so each time you are reducing the volume by 0
You don't need to parseInt(saudio.volume) since it's already a number too.
So this should work
var count = 0;
var rotate = 5;
var saudio = $("#saudio").get(0);
function tryitnow() {
count++;
saudio.volume = saudio.volume - 0.1;
if (count != rotate) {
setTimeout(function() {
tryitnow()
}, 1000);
}
}

How would you throttle a recursive function?

Let's suppose I want to run a recursive function that will take weeks, months or even years to complete. It returns all possible permutations of a string based on the specified parameters. While it's running, I want to be able to see how far along it is progressing - e.g. how many permutations it has generated so far. In a nutshell, I want a very long-running recursive function to execute without locking up my UI.
Also, I would like to do this with vanilla ES5, not in strict mode, and without WebWorkers. It should be able to run in IE9.
What I have works fine as-is, but when I raise numspaces to 10, for example, the browser locks up. So I am assuming that I am just working the browser too hard, and "throttling" the amount of work it has to do would help solve this problem. I did try increasing the setTimeout delays from 1 to 250 and even 1000, but the browser still locked up.
I am interested in this simply because I tried to do it, and couldn't. Also, I know for a fact that this code is terribly inefficient and there are much, much better ways to do what I am looking to achieve. So recommend them!
var inputString = "abcdefghijklmnopqrstuvwxyz";
function allPossibleCombinations(input, length, curstr, callback) {
if (curstr.length === length) return callback(curstr);
(function(n) {
setTimeout(allPossibleCombinations.bind(n, input, length, curstr + input[n], callback), 1);
n++;
if (n < input.length) setTimeout(arguments.callee.bind(n,n), 1);
})(0);
}
var totalResults = 0,
numDigits = inputString.length,
numSpaces = 2,
maxResults = Math.pow(numDigits, numSpaces),
consoleElement = document.getElementById('console'),
startTime = +new Date();
console.log("Starting.. expecting", maxResults, "total results...");
allPossibleCombinations(inputString.split(""), numSpaces, "", function(result) {
totalResults++;
if (totalResults === maxResults) {
var elapsed = +new Date() - startTime;
consoleElement.innerText = "Done.";
console.log("Completed in", elapsed, "ms!");
} else {
// Do something with this permutation...
//...
// Show progress...
var progress = ((totalResults / maxResults) * 100).toFixed(2) * 1;
consoleElement.innerText = progress + "%";
}
});
<div id="console"></div>
You’re getting close with the setTimeout, but the current implementation queues up all the timers for a given prefix at once, resulting in an exponential number of timers and quick memory exhaustion. One small change would be to create another callback to indicate completion and use it to wait on recursive calls, never holding more than one timer at once:
var inputString = "abcdefghijklmnopqrstuvwxyz";
function allPossibleCombinations(input, length, curstr, resultCallback, doneCallback) {
if (curstr.length === length) {
resultCallback(curstr);
doneCallback();
return;
}
var n = 0;
(function next() {
if (n === input.length) {
doneCallback();
return;
}
allPossibleCombinations(
input, length, curstr + input[n],
resultCallback,
function () {
n++;
setTimeout(next, 0);
});
})();
}
var totalResults = 0,
numDigits = inputString.length,
numSpaces = 4,
maxResults = Math.pow(numDigits, numSpaces),
consoleElement = document.getElementById('console'),
startTime = +new Date();
console.log("Starting.. expecting", maxResults, "total results...");
allPossibleCombinations(
inputString.split(""), numSpaces, "",
function (result) {
totalResults++;
// Do something with this permutation...
//...
// Show progress...
var progress = ((totalResults / maxResults) * 100).toFixed(2) * 1;
consoleElement.innerText = progress + "%";
},
function () {
var elapsed = +new Date() - startTime;
consoleElement.innerText = "Done.";
console.log("Completed in", elapsed, "ms!");
});
<div id="console"></div>
That’s really slow, though. Thinking of how you could write this as a generator:
function* strings(input, length, current) {
if (current.length === length) {
yield current;
return;
}
for (let i = 0; i < input.length; i++) {
yield* strings(input, length, current + input[i]);
}
}
and translating that to a system where the callback is responsible for resuming generation:
function strings(input, length, current, yield_, continue_) {
if (current.length === length) {
yield_(current, continue_);
return;
}
var i = 0;
(function next() {
if (i === input.length) {
continue_();
return;
}
strings(input, length, current + input[i++], yield_, next);
})();
}
you can have the flexibility of setting a timer as infrequently as you’d like for performance.
"use strict";
function countSequences(n, k) {
var result = 1;
for (var i = 0; i < k; i++) {
result *= n--;
}
return result;
}
function strings(input, length, current, yield_, continue_) {
if (current.length === length) {
yield_(current, continue_);
return;
}
var i = 0;
(function next() {
if (i === input.length) {
continue_();
return;
}
var c = input[i++];
strings(input.replace(c, ''), length, current + c, yield_, next);
})();
}
var inputString = "abcdefghijklmnopqrstuvwxyz";
var totalResults = 0;
var numDigits = inputString.length;
var numSpaces = 5;
var maxResults = countSequences(numDigits, numSpaces);
var consoleElement = document.getElementById('console');
var startTime = +new Date();
console.log("Starting… expecting", maxResults, "total results.");
strings(
inputString, numSpaces, "",
function (result, continue_) {
if (totalResults++ % 1000 === 0) {
var progress = (totalResults / maxResults * 100).toFixed(2);
consoleElement.innerText = progress + "% (" + result + ")";
setTimeout(continue_, 0);
} else {
continue_();
}
},
function () {
var elapsed = +new Date() - startTime;
consoleElement.innerText = "Done.";
console.log("Completed in", elapsed, "ms!");
});
<div id="console"></div>
(This style is still non-optimal, but it’ll never finish for 2610 no matter how quick individual operations are.)

Display a random number 25 times with a 320ms delay Js

I have been trying to find a answer for this but I couldn't really get it to work.
I need JavaScript code to display a random number 25 times with a 320ms delay for each number.
(Ignore the other things except for //start roll)
function roll() {
var win = Math.floor(Math.random() * 25) + 0
//change the button when rolling
rollButton.disabled = true;
rollButton.innerHTML = "Rolling...";
rollButton.style.backgroundColor = "grey";
rollButton.style.color = "black"
setTimeout(unDisable, 8000)
//start roll
(insert code here)
}
Thanks if you can help
You can use setInterval for make loop with some delay and clearInterval for stopping that loop !
$(function(){
t = 0;
var interval = setInterval(function(){
var win = Math.floor(Math.random() * 25) ;
var html = $('span').html();
$('span').html(html + win + '<br>')
t++;
if(t == 25)
stop();
}, 320);
function stop(){
clearInterval(interval);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span></span>
A simple thing you can do is simply:
function roll() {
//change the button when rolling
rollButton.disabled = true;
rollButton.innerHTML = "Rolling...";
rollButton.style.backgroundColor = "grey";
rollButton.style.color = "black"
setTimeout(unDisable, 8000)
//start roll
showNum(25)
}
const getRand = _ => Math.floor(Math.random() * 25) + 0
const showNum = n => {
if (n-- <= 0) {return}
document.getElementById("dispNum").innerHTML = getRand()
setTimeout(_ => showNum(n), 320)
}
It will keep spawning a new thread to print a random number while decrementing its iteration count, till it hits 0

Make number grow with jQuery using same amount of time for every number

My goal is to perform a jQuery script that'll make any number visually grow from zero until its value with setInterval().
Here's what I came up with:
$('.grow').each(function() {
var $el = $(this);
var max = parseInt($el.text().replace(/\s/g, ''));
var refresh = 5;
var start = 0;
var step = 1;
var interval = window.setInterval(function() {
start += step;
$el.text(start);
if(start >= max)
clearInterval(interval);
}, refresh);
});
My problem is I have numbers ranging from a few hundreds to several hundreds thousands. With this script, bigger number take more time to reach their value.
My goal is to make any number, regardless of its goal value, take the same amount of time to reach it. I sense that I should divide the number by the number of seconds I want the animation to run and then, set the result as the interval step?
I'm inquiring but still seeking for help :)
Thanks.
$('.grow').each(function() {
var $el = $(this);
var max = parseInt($el.text().replace(/\s/g, ''));
var duration = 1000; // shared duration of all elements' animation
var refresh = 5;
var frames = duration / refresh; // number of frames (steps)
var start = 0;
var step = Math.max(Math.round(max / frames), 1); // step should be >= 1
var interval = window.setInterval(function() {
if(start + step < max) {
start += step;
}
else {
start = max;
clearInterval(interval);
}
$el.text(start);
}, refresh);
});
This should work I suppose,
$('.grow').each(function() {
var $el = $(this);
var max = parseInt($el.text().replace(/\s/g, ''));
var start = 0;
var refresh = 5;
var totalSteps = 10;
var step = max/totalSteps;
function calculate(){
start += step;
$el.text(Math.round(start));
if(start < max){
setTimeout(function() {
calculate();
}, refresh);
}
}
calculate();
});
This will always finish in 100 steps. I.e. 100*refresh = 100*5 = 500 seconds.

Need help timing events with jquery

Here's my code:
tripper = 2;
$("#topheader").mousewheel(function(event, delta) {
if (tripper == 2){
startPlace = $("#content").scrollLeft();
startCounter = something;
tripper = 1;
} else {
currentPlace = $("#content").scrollLeft();
if(startCounter < 100){ // milliseconds
distanceMoved = currentPlace - startPlace;
if(distanceMoved > 100){
slideRight();
} else if(distanceMoved < -100){
slideLeft();
}
} else {
tripper = 2;
}
}
}
What is the proper way to check if 100 milliseconds has passed sense the first time through this function? In the 5th line of code i have the variable "something" which needs to be replaced with a counter of some sort. Or maybe I'm going about this in an entirely wrong way. Suggestions?
You can instantiate a "Date" object like this:
var then = new Date();
Later you can make another one:
var now = new Date();
Subtraction gives the difference in milliseconds:
var elapsed = now - then;
(The coercion from "Date" to "Number" is implicit when the two date values appear on either side of the subtraction operator. The conversion is just like calling "now.getTime()".)
The following code it is untested but basically, after 100 milliseconds, it should reset timeout back to null and ultimately set tripper back to 2;
tripper = 2;
timeout = null;
$("#topheader").mousewheel(function(event, delta) {
if (tripper == 2){
startPlace = $("#content").scrollLeft();
if (!timeout) {
setTimeout(function() {
timeout = null
}, 100);
}
tripper = 1;
} else {
currentPlace = $("#content").scrollLeft();
if(timeout){ // milliseconds
distanceMoved = currentPlace - startPlace;
if(distanceMoved > 100){
slideRight();
} else if(distanceMoved < -100){
slideLeft();
}
} else {
tripper = 2;
}
}
}

Categories