I am trying to implement a moving waiting bar in JavaScript. This is supposed to be visible during an AJAX request.
My initial code seems to work, but has the restriction that it can be used only once on the page, since there is only the variables timerW and stateW only appear once as global variable, and the element ids can also appear only once in the html document.
var timerW;
var stateW = 1;
function nextW(){
switch (stateW){
case 1:
document.getElementById('d3').style.background = "grey";
document.getElementById('d1').style.background = "red";
stateW++;
timerW = setTimeout("nextW()",250);
break;
case 2:
document.getElementById('d1').style.background = "grey";
document.getElementById('d2').style.background = "red";
stateW++;
timerW = setTimeout("nextW()",250);
break;
case 3:
document.getElementById('d2').style.background = "grey";
document.getElementById('d3').style.background = "red";
stateW = 1;
timerW = setTimeout("nextW()",250);
break;
}
}
function Wait(mainE){
document.getElementById(mainE).innerHTML = '<div id="d1" class="d"></div><div id="d2" class="d"></div><div id="d3" class="d"></div>';
nextW(mainE);
}
So, from there I want to extend it to make it possible to have multiple wait blocks visible.
The first problem I try to solve is the html generated, so have unique ID's
var timerW;
var stateW = 1;
function nextW(mainE){
// Unexplained behaviour
// for some reason, I get the HTMLDivElement in stead of it's ID in a string,
// This appears to start when stateW is 3.
// the setTimeout in case 1 looks identical to the case 2, so I have no clue why
// I am getting an object in stead of my string.
var m;
if (typeof(mainE)=="object") {
m = mainE;
mainE = m.id;
} else {
m = document.getElementById(mainE);
}
if (m == undefined ) return;
if (m.style.visibility == "hidden") return;
for(i=0; i < m.children.length; i++) {
if (m.children[i].id=="wait") {
m = m.children[i];
break;
}
}
if (stateW[mainE]==undefined) stateW[mainE] = 1;
switch (stateW[mainE]){
case 1:
for(i=0; i < m.children.length; i++) {
var e = m.children[i];
if (e.id==mainE+'d1'){
e.style.background = "red";
} else {
e.style.background = "gray";
}
}
stateW++;
timerW = setTimeout("nextW("+mainE+")",250);
break;
case 2:
for(i=0; i < m.children.length; i++) {
var e = m.children[i];
if (e.id==mainE+'d2'){
e.style.background = "red";
} else {
e.style.background = "gray";
}
}
stateW++;
timerW = setTimeout("nextW("+mainE+")",250);
break;
case 3:
for(i=0; i < m.children.length; i++) {
var e = m.children[i];
if (e.id==mainE+'d3'){
e.style.background = "red";
} else {
e.style.background = "gray";
}
}
stateW = 1;
timerW = setTimeout("nextW("+mainE+")",250);
break;
}
}
function Wait(mainE){
document.getElementById(mainE).innerHTML = '<div id="wait"><div id="'+mainE+'d1" class="d"></div><div id="'+mainE+'d2" class="d"></div><div id="'+mainE+'d3" class="d"></div></div>';
nextW(mainE);
}
This code results in unexplained behaviour. As I set the timer using
timerW = setTimeout("nextW("+mainE+")",250);
in each case, the 2nd block is drawn red correctly, but after that, I am getting an HTMLDivElement in stead of the string I expected. The HTMLDivElement corresponds with the ID in the string I expect. I cannot explain why, only after the 2nd block is drawn red, the behaviour changes. It keeps giving me an HTMLDivElement consequently after the 2nd red block, but I cannot explain why.
So far so good, I can write code around this little problem, even though I cannot explain why this is happening.
Still, the code is not ready yet for multiple wait timers running at the same time. For this, I tried to create two objects
var timerW = new Object();
var stateW = new Object();
and replace my
switch (stateW){
with
if (stateW[mainE]==undefined) stateW[mainE] = 1;
switch (stateW[mainE]){
and replace
timerW = setTimeout("nextW("+mainE+")",250);
with
timerW[mainE] = setTimeout("nextW("+mainE+")",250);
Now, the problem is, my objects turn into NaN after the first run through my nextW function. I expect it's caused by garbage collection.
Can anyone explain (1) Why I am getting HTMLDivElements in stread of strings? (2) Why my Object turns into a NaN? (3) How to fix this issue?
I am not just looking for a fix, but also wanting to know what is going on.