Change Label Text Periodically Javascript - javascript

I try to change a label's text periodically by using the following code:
function sleep(milliSeconds) {
var startTime = new Date().getTime();
while (new Date().getTime() < startTime + milliSeconds);
}
function showMap() {
var str = document.getElementById("lbPoints").firstChild.nodeValue;
var lbl = document.getElementById("my");
var strs = str.split("-");
var millisecondsToWait = 500;
for (var i = 0; i < strs.length-1; i++) {
lbl.innerHTML = strs[i];
sleep(500);
}
}
My "str" and "strs" are right. Code works, but as waits for 5 seconds and print the final string in strs to screen and nothing else. What can I do to change it periodically?

That's not how you sleep. In no language is it correct to test repeatedly
until a date.
Do this instead :
function showMap() {
var str = document.getElementById("lbPoints").firstChild.nodeValue;
var lbl = document.getElementById("my");
var strs = str.split("-");
var millisecondsToWait = 500;
var i=0;
var interval = setInterval(function(){
if (i==strs.length-2) clearInterval(interval);
lbl.innerHTML = strs[i++];
}, millisecondsToWait);
}
Demonstration
This uses setInterval to call repeatedly a function, and clearInterval at the end of array to stop the function being called.

Just use setInterval, that's what it's for. From the documentation:
Calls a function or executes a code snippet repeatedly, with a fixed
time delay between each call to that function.

Related

Java Script iframe src change links by order instead of random

I am trying change iframe src automatically with java script. But it's works in randomly. I want this works on by order and also change milliseconds to minutes..!
var pages=new Array();
pages[0]="http://www.virtusa.com";
pages[1]="https://www.listertechnologies.com/";
pages[2]="https://intellectdesign.com/";
var time=600000; // this is set in milliseconds
function pageChange() {
var rand=Math.floor(Math.random()*pages.length);
document.getElementById("frame").src=pages[rand];
setTimeout("pageChange()",time);
}
onload=pageChange;
var pages = new Array();
pages[0] = "http://www.virtusa.com";
pages[1] = "https://www.listertechnologies.com/";
pages[2] = "https://intellectdesign.com/";
var index = 0;
var minute = 60000;
var time = 10 * minute;
function pageChange() {
var rand = pages[index];
document.getElementById("frame").src = rand;
setTimeout(pageChange, time);
index = index == pages.length - 1 ? 0 : index + 1;
}
onload = pageChange;

How define a couple of setIntervals and clear them with delay

I need to randomly change characters of a text and after some delay fix them.
There is my code:
<h1 id="text" style="margin-top:100px;">SOME TEXT</h1>
<script>
var text = document.getElementById("text").innerHTML.split("");
var myArr = text;
for (i = 0; i < myArr.length; ++i) {
var handle = setInterval(function () { xyz(i) }, 100);
setTimeout(function (handle) {
myArr[i] = text[i];
clearInterval(handle);
}, (i) * 1000);
}
function xyz(index) {
myArr[index] = String.fromCharCode(Math.random() * 26 + 65);
document.getElementById("text").innerHTML = myArr;
}
</script>
It seems i have no a good understanding of how setInterval work! :(
EDIT:
With my code only text[text.length+1] character has change that mean passed parameter to xyx() function is last value of loop counter variable (after loop over). Now my question is how trigger setInterval() function with i = 0 ,1 ... , text.length.
Can someone guide me?
basicly setInterval execute a function with a iteration in time. and setInterval gives you a promise to cancel it any time you want.
var myPromise = setInterval(function(){
//some code here
},delayMiliseconds);
to cancel this code
clearInterval(myPromise);
Related to this question problem was wrong way to passing arguments to setInterval().the callback function i passed to setInterval() maintains a reference to "i" rather than the snapshot value of "i" as it existed during each particular iteration...
<h1 id="text" style="margin-top:100px;">SOME TEXT</h1>
<script>
var text = document.getElementById("text").innerHTML.split("");
var myArr = document.getElementById("text").innerHTML.split("");
for (i = 0; i < text.length; i++) {
var handle = setInterval(function (k) { xyz(k) }, 100,i);
setTimeout(function (handle, i) {
console.log(i);
console.log(text[i]);
myArr[i] = text[i];
clearInterval(handle);
}, (i) * 1000,handle,i);
}
function xyz(index) {
myArr[index] = String.fromCharCode(Math.random() * 26 + 65);
document.getElementById("text").innerHTML = myArr.toString();
}
</script>

iterate through JSON object with pause before next iteration

I am trying to build a fake chat box. I can retrieve the data from the database using jQuery to return a JSON array ok. I then i want each line of text contained in the JSON object to display on the page one line at a time BUT the code must pause for the length of time it would normally take to type the line if text before it displays it. then the code must wait for it to be displayed before it iterated on to the next value in the JSON object.
I hope all that makes sense...
$.getJSON('includes/get-mentor-dialogue.php?e=' + new Date().getTime(), function(data){
var mainDialogue = data.item;
var l = mainDialogue.length;
$.each(mainDialogue, function(index, d){
var delay = Math.round(countWords(d.content) / WPS) * 1000;
setTimeout(function(){$('#chatBox #chatBody').append('<p>'+ d.content +'</p>');},delay);
});
});
This is what i have and it kinda works... countWords() is a function that returns the number of words in the sentence and WPS is a variable that contains the average "Words Per Second" value in it.
The issue is that all the lines of text are displayed out of sequence. i can't get it to wait for the previous line to be displayed before it moves on to the next one...
Really need help with this one guys...
You can use a function to iterate with timeout, without using the $.each, see below
$.getJSON('includes/get-mentor-dialogue.php?e=' + new Date().getTime(), function(data){
var mainDialogue = data.item;
var l = mainDialogue.length;
var actual = -1;
function showNextMessage(){
actual++;
if( actual >= l ) return;
var content = mainDialogue[actual].content;
var delay = Math.round(countWords(content) / WPS) * 1000;
setTimeout(function(){
$('#chatBox #chatBody').append('<p>'+ content +'</p>');
showNextMessage();
},delay);
}
showNextMessage();
});
I think this will work for you.
$.getJSON('includes/get-mentor-dialogue.php?e=' + new Date().getTime(), function(data){
var mainDialogue = data.item;
var l = mainDialogue.length;
var i = 0;
function appendText(content) {
var delay = Math.round(countWords(content) / WPS) * 1000;
if ( i < l - 1 ) {
setTimeout(function(){
$('#chatBox #chatBody').append('<p>'+ content +'</p>');
appendText(mainDialogue[i++].content);
}, delay);
}
};
appendText(mainDialogue[i++].content);
});
I usually create an Iterator class, somewhere along the lines of this:
Iterator = function (iterable) {
var keys = [];
for (var i in iterable)
keys.push(i);
var pointer = 0;
this.next = function () {
return keys[pointer++];
}
this.hasNext = function () {
return i < keys.length;
}
}
That way you don't have to directly iterate across the object, you can just easily keep track of your place in the object as you would in Java.
$.getJSON('includes/get-mentor-dialogue.php?e=' + new Date().getTime(), function(data){
var mainDialogue = data.item;
var l = mainDialogue.length;
var iter = new Iterator(mainDialogue);
(function appendChat () {
var d = iter.next();
var delay = Math.round(countWords(d.content) / WPS) * 1000;
$('#chatBox #chatBody').append('<p>'+ d.content + '</p>');
if (iter.hasNext())
setTimeout(appendChat, delay);
})();
});
I don't have a good way to test this, but you should look into doing something like this:
$.getJSON('includes/get-mentor-dialogue.php?e=' + new Date().getTime(), function(data){
var mainDialogue = data.item;
var l = mainDialogue.length;
var delay = 0;
$.each(mainDialogue, function(index, d){
var myDelay = Math.round(countWords(d.content) / WPS) * 1000;
myDelay+=delay; // how long it takes me to render + the guy before me
delay=myDelay + (Math.random()*2000); // this will give a random pause between each step
setTimeout(function(){$('#chatBox #chatBody').append('<p>'+ d.content +'</p>');},myDelay);
});
});
I added in that little random bit, to help give a more realistic variable timing to the chat sequence.

Stopping setInterval

I am playing around with "ID's" trying to get comfortable and such. I know jQuery has a really quick solution, but I want to know how to do it via js.
var startTimer = function init(){
var n = 0;
var e = document.getElementById("output");
var myTimer = setInterval (function() {e.innerHTML = n++;},100);
// clearInterval(myTimer);
if(myTimer === 10){
clearInterval(myTimer);
return;
}
}
startTimer();
Did you actually want this?
function initTimer(){
var n = 0;
var e = document.getElementById("output");
var timerid = setInterval( function() {
e.innerHTML = n;
if (n < 10) // count until ten
n++;
else
clearInterval(timerid); // this happens somewhen later
}, 100);
}
You're comparing myTimer to 10, you should compare n instead:
if(n===10) ...

setTimeout inside for loop [duplicate]

This question already has answers here:
setTimeout in for-loop does not print consecutive values [duplicate]
(10 answers)
Closed 7 years ago.
I want a string to appear character-for-character with the following code:
function initText()
{
var textScroller = document.getElementById('textScroller');
var text = 'Hello how are you?';
for(c = 0; c < text.length; c++)
{
setTimeout('textScroller.innerHTML += text[c]', 1000);
}
}
window.onload = initText;
It's not working.. what am I doing wrong?
Try something like this:
function initText()
{
var textScroller = document.getElementById('textScroller');
var text = 'Hello how are you?';
var c = 0;
var interval = setInterval(function() {
textScroller.innerHTML += text[c];
c++;
if(c >= text.length) clearInterval(interval);
}, 1000);
}
Note I added clearInterval to stop it when it's needed.
Currently, you are defining 18 timeouts and all will be executed ~ at once.
Second problem is, you pass instructions to execute as a String. In that case, the code won't have access to all variables defined in initText, because evaluated code will be executed in global scope.
IMO, this should do the job
function initText(){
var textScroller = document.getElementById('textScroller');
var text = 'Hello how are you?';
var c = 0;
(function(){
textScroller.innerHTML += text.charAt(c++);
if(text.length > c){
setTimeout(arguments.callee, 1000);
}
})();
}
Even more generic than answer by #yauhen-yakimovich:
Using Timeout:
var repeat = (function () {
return function repeat(cbWhileNotTrue, period) {
/// <summary>Continuously repeats callback after a period has passed, until the callback triggers a stop by returning true. Note each repetition only fires after the callback has completed. Identifier returned is an object, prematurely stop like `timer = repeat(...); clearTimeout(timer.t);`</summary>
var timer = {}, fn = function () {
if (true === cbWhileNotTrue()) {
return clearTimeout(timer.t); // no more repeat
}
timer.t = setTimeout(fn, period || 1000);
};
fn(); // engage
return timer; // and expose stopper object
};
})();
Using Interval:
var loop = (function () {
return function loop(cbWhileNotTrue, period) {
/// <summary>Continuously performs a callback once every period, until the callback triggers a stop by returning true. Note that regardless of how long the callback takes, it will be triggered once per period.</summary>
var timer = setInterval(function () {
if (true === cbWhileNotTrue()) clearInterval(timer);
}, period || 1000);
return timer; // expose stopper
};
})();
Slight difference between the two indicated in comments -- the repeat method only repeats after the callback performs, so if you have a "slow" callback it won't run every delay ms, but repeats after every delay between executions, whereas the loop method will fire the callback every delay ms. To prematurely stop, repeat uses an object as the returned identifier, so use clearTimeout(timer.t) instead.
Usage:
Just like answer by #soufiane-hassou:
var textScroller = document.getElementById('textScroller');
var text = 'Hello how are you?';
var c = 0;
var interval = repeat/* or loop */(function() {
textScroller.innerHTML += text[c];
c++;
return (c >= text.length);
}, 1000);
As mentioned, premature stopping would be:
/* if repeat */ clearTimeout(interval.t);
/* if loop */ clearInterval(interval);
Try this:
function initText()
{
var textScroller = document.getElementById('textScroller');
var text = 'Hello how are you?';
for(c = 0; c < text.length; c++)
{
setTimeout("textScroller.innerHTML += '" + text[c] + "'", 1000 + c*200);
}
}
window.onload = initText;
Try using a closure:
function init() {
var textScroller = document.getElementById('textScroller');
var text = 'Hello how are you?';
var c = 0;
function run() {
textScroller.innerHTML += text[c++];
if (c<text.length)
setTimeout(run, 1000);
}
setTimeout(run, 1000);
}
init()
The problem in your code is that the code you put in the string will run in the global context, where textScroller is not defined (it is defined inside your function).
I want to share a snippet (based on answer by Soufiane Hassou). It extends to the case when you literally replace a for-loop body to be iterated over some array in a fixed interval of time. Basically same synchronous loop but with "sleep" pausing (because javascript is not a synchronous programming language).
function loop(arr, take, period) {
period = period || 1000;
var i = 0;
var interval = setInterval(function() {
take(i, arr[i]);
if (++i >= arr.length) { clearInterval(interval);}
}, period);
}
Usage example:
loop([1, 2, 3, 4], function(index, elem){
console.log('arr[' + index + ']: ' + elem);
});
Tested in Node JS. Hope that helps someone.
edit>
the following update makes code usable together with libs doing heavy "prototyping" (like jQuery or prototype):
function loop(arr, take, period) {
period = period || 1000;
var scope = {
i: 0,
arr: arr,
take: take,
};
var iterate = (function iterate() {
if (this.i >= this.arr.length) { clearInterval(this.interval); return}
take(this.i, this.arr[this.i++]);
}).bind(scope);
scope.interval = setInterval(iterate, period);
}
Your for loop is setting a timeout for every character at once, so they will not appear in sequence, but all at once. Your setTimeout should include code to another setTimeout that will include the next character to display.
So something like this (didn't test this)
function initText()
{
var textScroller = document.getElementById('textScroller');
var text = 'Hello how are you?';
setTimeout('nextChar(text)', 1000);
}
function nextChar(text){
if(text.length > 0){
textScroller.innerHTML += text[0];
setTimeout('nextChar(text.substring(1))', 1000);
}
}
If you want to preserve setTimeOut (instead of setInterval) and use named function (instead of evaluating code block in setTimeOut call), then this could be helpful:
var b = {
textScroller: document.getElementById('textScroller'),
text: "Hello how are you?"
};
function initText() {
for(c = 0; c < b.text.length; c++) {
setTimeout("append("+c+")", 1000 + c*200);
}
}
function append(c) {
b.textScroller.innerHTML += b.text[c];
}
window.onload = initText;
With the above you can pass a parameter to append function.
To pass several parameters the next code does the trick:
var glo = [];
function initText()
{
var textScroller = document.getElementById('textScroller');
var text = "Hello how are you?";
var timeout_time;
for(c = 0; c < text.length; c++) {
glo[glo.length] = {text:text, c:c, textScroller:textScroller};
timeout_time = 1000 + c * 200;
setTimeout("append(" + (glo.length - 1) + ")", timeout_time);
}
}
function append(i)
{
var obj = glo[i];
obj.textScroller.innerHTML += obj.text[obj.c];
obj = null;
glo[i] = null;
}
window.onload = initText;
With the above you have only one global array glo. In loop you create new array members to glo and in append() function refer to these members using index which is passed as parameter.
CAUTION: the second code sample is not meant as best or most suitable solution to OP:s problem, but may benefit in other setTimeOut relative problems, eg. when someone wants to make a presentation or performance test where some functionalities are needed to call after some delay. The advantage of this code is to make use of for loops (many coders want to use for loops) and the possibility to use also inner loops and the ability to "send" local variables in their loop time state to timeOut functions.
May be better to loop in cascade. For exemple to fade a div :
div=document.createElement('div');
div.style.opacity=1;
setTimeout(function(){fade(1);},3000);
function fade(op){
op-=.05;
if(op>0) setTimeout(function(){div.style.opacity=op;fade(op);},30);
else document.body.removeChild(div);
}

Categories

Resources