Show elements of array one by one - Jquery - javascript

So I have a button on which I want to display each element of my array for a few seconds. This is my html code:
<button class="btn" id="random">Start</button>
I have made an array with jQuery that I want to use to change the buttons text:
$(document).ready(function() {
$("#random").on("click", loop);
});
var array = ["el1","el2","el3"];
function loop() {
for (i = 0; i < array.length; i++) {
$("#random").html(array[i]);
}
var random = Math.floor(Math.random() * array.length) + 1;
$("#random").html(array[random]);
}
The for loop is supposed to do what I want but I can't find a way to delay the speed, it always just shows the last line of code. When I try setTimeout or something it just looks like it skips the for loop.

My proposal is to use IIFE and delay:
var array = ["el1","el2","el3", "Start"];
function loop(){
for (i = 0; i < array.length; i++){
(function(i) {
$("#random").delay(1000).queue(function () {
$(this).html(array[i]);
$(this).dequeue();
});
})(i);
}
}
$(function () {
$("#random").on("click", loop);
});
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<button class="btn" id="random">Start</button>

Basically, a for loop will not help you. It runs with the max speed it can. And delaying it would do no good in js (you would just freeze the browser). Instead, you can just make a function that will execute itself with a delay. Kinda recursion, but not entirely. Below would make the trick.
https://jsfiddle.net/7dryshay/
$(document).ready(function() {
$("#random").on("click", function (event) {
// texts to cycle
var arr = ["el1","el2","el3"];
// get the button elem (we need it in this scope)
var $el = $(event.target);
// iteation function (kinda recursive)
var iter = function () {
// no more stuff to display
if (arr.length === 0) return;
// get top of the array and set it on button
$el.text(arr.shift());
// proceed to next iteration
setTimeout(iter, 500);
}
// start first iteration
iter();
});
});

Use setInterval() and clearInterval()
$(document).ready(
function() {
$("#random").on("click", loop);
}
);
var array = ["el1", "el2", "el3"];
var int;
function loop() {
var i = 0; // variable for array index
int && clearInterval(int); // clear any previous interval
int = setInterval(function() { //store interval reference for clearing
if (i == array.length) clearInterval(int); // clear interval if reached the last index
$("#random").text(i == array.length ? 'Start' : array[i++]); // update text with array element atlast set back to button text
}, 1000);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button class="btn" id="random">Start</button>
UPDATE : If you need to implement it using for loop and setTimeout() then do something like this
var array = ["el1", "el2", "el3", "Start"];
function loop() {
for (i = 0; i < array.length; i++) {
(function(i) {
setTimeout(function() {
$("#random").html(array[i]);
}, i * 1000);
})(i);
}
}
$(function() {
$("#random").on("click", loop);
});
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<button class="btn" id="random">Start</button>

Related

jQuery/JavaScript: Initiate and terminate a loop with the same button

I want to build a button that when I click it, the function in JavaScript associated with it initiates (so a loop inside it start doing something).
If I click it again before the loop inside the function finishes, the loop will terminates.
If I click it again after the loop inside the function has already finished, the loop will just start as usual.
How do I do this with the following code?
Thanks in advance.
HTML:
<button id="startstop" class="btn btn-primary" onclick="count()">
JavaScript:
function count() {
var val = 0;
var loop = setInterval(function(){
val++;
if (val > 1000} {
clearInterval(loop);
}
}, 100);
}
try this code
var loop;
function count() {
var val = 0;
if (loop) {
clearInterval(loop);
loop = null;
}
else{
loop = setInterval(function(){
val++;
console.log(val);
if (val > 1000) {
clearInterval(loop);
loop = null;
}
}, 100);
}
}
I'm not a big fan of doing work for people, but on this occasion I'll succumb...
You need to store the internal ID outside of the function, and base your process on that. If the ID is not set, start the interval, if it is set stop the interval.
Note, that I've massively reduced the length of interval, and the number of times it fires for this example...
var _intervalId = -1;
function count() {
if (_intervalId == -1) {
var val = 0;
_intervalId = setInterval(function(){
val++;
if (val > 200) {
clearInterval(_intervalId);
_intervalId = -1
document.getElementById("output").innerHTML = "stopped automatically";
}
}, 10);
document.getElementById("output").innerHTML = "started";
} else {
clearInterval(_intervalId);
_intervalId = -1;
document.getElementById("output").innerHTML = "stopped manually";
}
}
<button onclick="count();return false">Click Here</button>
<div id="output"></div>
Place loop variable in global scope and everytime the user clicked stop previous loop if it's already started if not start it.
Hope this helps.
var loop=null;
count = function () {
var val = 0;
//Stop previous loop if it's already started
if(loop!=null){
clearInterval(loop);
loop=null;
}else{
loop = setInterval(function(){
val++;
console.log(val);
$('span').text(val);
if (val >= 20) {
clearInterval(loop);
}
}, 100);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="startstop" class="btn btn-primary" onclick="count()">Count</button>
<span>0</span>
I had fun building a small class for this. Feel free to use.
// Counter class
function Counter(callback, speed, max, init){
var loop = null;
this.callback = callback;
this.value = init || 0;
this.max = max;
function count(){
if (this.max && this.value >= this.max) {
clearInterval(loop);
loop = null;
} else {
this.value++;
}
this.callback(this.value);
}
this.start = function(){
if(!this.isStarted){
loop = setInterval(count.bind(this), speed);
}
};
this.stop = function(){
if(this.isStarted){
clearInterval(loop);
loop = null;
}
}
Object.defineProperty(this, "isStarted", { get: function(){
return !!loop;
}});
}
// Usage example.
var result = document.getElementById("counter");
var button = document.getElementById("startstop");
// Create the counter and the callback.
var counter = new Counter(function(val){
result.innerHTML = val;
}, 100, 1000);
// Init the result value.
result.innerHTML = counter.value;
// Listen for click events on the button.
button.addEventListener("click", function(){
if(counter.isStarted){
counter.stop();
} else {
counter.start();
}
});
<div id="counter"></div>
<button id="startstop">Toggle</button>

For loop using jQuery and JavaScript

I'm trying to do a simple for loop in JavaScript/jQuery
every time I click NEXT, I want the I to increment once.
But it is not working. When I press next, nothing happens.
<script>
//function to show form
function show_form_field(product_field){
$(product_field).show("slow");
}
$(document).ready(function(){
//start increment with 0, until it is reach 5, and increment by 1
for (var i=0; i < 5 ;i++)
{
//when I click next field, run this function
$("#next_field").click(function(){
// fields are equial to field with id that are incrementing
var fields_box = '#field_'+[i];
show_form_field(fields_box)
})
}
});
</script>
You do not need the for loop. Just declare var i outside click function and increment it inside the function.
//function to show form
function show_form_field(product_field) {
$(product_field).show("slow");
}
$(document).ready(function () {
var i = 0; // declaring i
$("#next_field").click(function () {
if (i <= 5) { // Checking whether i has reached value 5
var fields_box = '#field_' + i;
show_form_field(fields_box);
i++; // incrementing value of i
}else{
return false; // do what you want if i has reached 5
}
});
});
You should declare variable i document wide, not inside the click handler.
//function to show form
function show_form_field(product_field){
$(product_field).show("slow");
}
$(document).ready(function(){
var i=0;
$("#next_field").click(function(){
var fields_box = '#field_'+ i++ ;
show_form_field(fields_box)
})
});
Call $("#next_field").click just one time, and in the click function, increase i every time.
$(document).ready(function() {
var i = 0;
$("#next_field").click(function() {
if (i >= 5) {
//the last one, no more next
return;
}
show_form_field('#field_' + (i++));
});
});
try this
$(document).ready(function(){
//start increment with 0, untill it is reach 5, and increment by 1
var i = 0;
$("#next_field").click(function(){
// fields are equial to field with id that are incrementing
if(i<5)
{
var fields_box = '#field_'+i;
show_form_field(fields_box);
i+=1;
}
else
{
return;
}
});
});

JavaScript how to reverse this animation, after click another link

$('#home').click(doWork);
function doWork() {
var index = 0;
var boxes = $('.box1, .box2, .box3, .box4, .box5, .box6');
function start() {
boxes.eq(index).addClass('animated');
++index;
setTimeout(start, 80);
};
start();
}
when i click a link, this animation start . And after end the animation, i need to reverse this animation, after click another link.
Here's code that allows you to start the process, as well as interrupt it to do the reverse:
(function () {
"use strict";
var doWork,
index,
boxes,
numBoxes,
workerTO;
index = 0;
boxes = $(".box1, .box2, .box3, .box4, .box5, .box6");
numBoxes = boxes.length;
doWork = function (changer, reverse) {
var direction, worker;
clearTimeout(workerTO);
direction = reverse ? -1 : 1;
worker = function () {
if (reverse) {
if (index < 0) {
index = 0;
return;
}
} else {
if (index >= numBoxes) {
index = numBoxes - 1;
return;
}
}
console.log(index);
changer(boxes.eq(index));
index += direction;
workerTO = setTimeout(worker, 80);
};
worker();
};
$("#home").click(function () {
doWork(function (el) {
el.addClass("animated");
});
});
$("#home2").click(function () {
doWork(function (el) {
el.removeClass("animated");
}, true);
});
}());
DEMO: http://jsfiddle.net/NcdZT/1/
I'm sure some things could be condensed and made more efficient (like the if statements), but this seems readable and achieves what you want.
Keeping track of the setTimeout allows the process to be interrupted. If you increased the timeout from 80 to something more noticeable (or if you click fast enough), you would see that the "animation" can be reversed midway through.

setInterval won't get out of loop

The following javascript code takes randomly selected value from a array and types it in the input box. I've used jquery. I want to end setInterval "zaman2", so after It ends I can retype the next random string to the input box. But the loop doesn't end and gets stuck. How can I solve this?
Link to jsFiddle: http://jsfiddle.net/AQbq4/4/
var dersler = [...very long list...];
var zaman = setTimeout(function() {
var yeniDers = dersler[Math.floor(Math.random()*dersler.length)];
sayac = 0;
var zaman2 = setInterval(function() {
var harf = yeniDers.slice(0,(sayac+1));
sayac++;
$('#main-search').attr('placeholder', harf).typeahead({source: dersler});
if (sayac == yeniDers.length) {
clearInterval(zaman2);
}
},450);
},2000);
Don't you mean
DEMO
var tId, tId2;
function show() {
var ran = arr[Math.floor(Math.random()*arr.length)];
cnt = 0;
tId = setInterval(function() {
var char = ran.slice(0,(cnt+1));
cnt++;
$( '#main-search' ).attr('placeholder', char);
if (cnt == ran.length) {
clearInterval(tId);
tId2=setTimeout(show,2000);
}
},450);
}
show();

How to stop my javascript countdown?

How can I stop my javascript function when countdown = 0?
JS:
var settimmer = 0;
$(function(){
window.setInterval(function() {
var timeCounter = $("b[id=show-time]").html();
var updateTime = eval(timeCounter)- eval(1);
$("b[id=show-time]").html(updateTime);
}, 1000);
});
HTML:
<b id="show-time">20</b>
For one thing remove those evals. They don't do anything.
Then all you have to do is clear the timer when it reaches zero.
$(function(){
var timer = setInterval(function() {
var timeCounter = parseInt($("b[id=show-time]").text());
$("b[id=show-time]").text(--timeCounter); // remove one
if(!timeCounter) clearInterval(timer);
}, 1000);
});
It is easy! When you call setInterval it return an ID, so you can destroy the interval later. To destroy it you must use clearInterval(id), and voilà!
It works like this:
// Activate timer
var iv = window.setInterval(...);
// Deactive timer
window.clearInterval(iv);
Also you should use parseInt() instead of eval():
$(function() {
// Read the start value once and store it in a variable
var timeCounter = parseInt( $("b[id=show-time]").text() );
// Active the counter
var iv = window.setInterval(function() {
// Decrement by one and write back into the document
$("b[id=show-time]").text(--timeCounter);
// Check if counter == 0 -> stop counting
if (0 == timeCounter) {
window.clearInterval(iv);
// ...do whatever else needs to be done when counter == 0 ..
}
}, 1000);
});
Example:
var i = 0,
pid = setInterval(function() {
if (++i > 10)
clearInterval(pid);
}, 1000);
Based on what you wanted for your code ...
$(function() {
var el = document.getElementById('show-time'),
pid = setInterval(function() {
// (s - i) coerces s to Number
var t = el.innerHTML - 1;
el.innerHTML = t;
if (t < 1)
clearInterval(pid);
}, 1000);
});
Keep in mind that JS won't be 100% accurate with its timing.
Pasted code below or see the fiddle: http://jsfiddle.net/raHrm/
<script type="text/javascript">
$(function(){
var settimmer = 0,
timeCounter = $("#show-time").html(),
updateTime = timeCounter;
(function countDown() {
timeCounter = $("#show-time").html();
updateTime = parseInt(timeCounter)-1;
$("#show-time").html(updateTime);
if ( updateTime ) {
setTimeout(countDown, 1000);
}
})();
});​
</script>
Set the timer to a variable, then use clearInterval in-order to stop the loop. As for catching the end, use a simple conditional:
$(function(){
var elem=$('strong[id="show-time"]'),settimmer=0,updateTime,t;
t=window.setInterval(function() {
updateTime=parseFloat(elem.html(),10)-1;
if(updateTime==0) {
window.clearInterval(t);
elem.html('Done!');
} else {
elem.html(updateTime);
}
},1000);
});
Then in the HTML:
<strong id="show-time">20</strong>
The <b> tag is depreciated, try to avoid using it. Also, there is no reason to eval() the HTML you are getting from the element; a simple parseFloat() works just fine.

Categories