我正在尝试在JavaScript中实现移动等待栏。 这应该在AJAX请求期间可见。
我的初始代码似乎有效,但有限制,它只能在页面上使用一次,因为只有变量timerW和stateW只出现一次作为全局变量,并且元素id也只出现一次在html文档中。
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);
}
所以,从那里我想扩展它以使多个等待块可见。
我尝试解决的第一个问题是生成的html,所以有唯一的ID
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);
}
此代码导致无法解释的行为。当我使用
设置计时器时 timerW = setTimeout("nextW("+mainE+")",250);
在每种情况下,第二个块都正确地绘制红色,但在那之后,我得到一个HTMLDivElement而不是我期望的字符串。 HTMLDivElement与我期望的字符串中的ID相对应。我无法解释为什么,只有在第二个块被绘制为红色后,行为才会发生变化。它继续在第二个红色区块后给我一个HTMLDivElement,但我无法解释原因。
到目前为止,我可以围绕这个小问题编写代码,即使我无法解释为什么会这样。
但是,对于同时运行的多个等待计时器,代码还没有准备好。 为此,我尝试创建两个对象
var timerW = new Object();
var stateW = new Object();
并替换我的
switch (stateW){
与
if (stateW[mainE]==undefined) stateW[mainE] = 1;
switch (stateW[mainE]){
并替换
timerW = setTimeout("nextW("+mainE+")",250);
与
timerW[mainE] = setTimeout("nextW("+mainE+")",250);
现在问题是,在第一次运行nextW函数后,我的对象变成了NaN。 我希望它是由垃圾收集引起的。
任何人都可以解释 (1)为什么我在stread of strings中获取HTMLDivElements? (2)为什么我的物体会变成NaN? (3)如何解决这个问题?
我不只是在寻找解决方案,而且还想知道发生了什么。
答案 0 :(得分:3)
构造函数
function Wait(el) {
if (typeof el == "string") el = document.getElementById(el);
this.el = el;
this.state = 1;
this.el.innerHTML = '<div id="d1" class="d"></div>\
<div id="d2" class="d"></div>\
<div id="d3" class="d"></div>';
this.next();
}
动画步骤
Wait.prototype.next = function () {
if (this.el.style.visibility == "hidden") return;
var children = this.el.childNodes;
for (var i = children.length; i--;) {
if (children[i].id == "wait") {
var wait = children[i];
break;
}
}
children = wait.childNodes;
for (var i = children.length; i--;) {
var child = children[i];
if (child.id == this.el.id + 'd' + this.state) {
child.style.background = "red";
} else {
child.style.background = "gray";
}
}
this.state++;
if (this.state > 3) this.state = 0;
this.timer = setTimeout(this.next, 250);
}
<强>用法强>
new Wait("element_id");
答案 1 :(得分:0)
解释一下,错了:
setTimeout("nextW("+mainE+")",250);
首先:不要为setTimeout()提供字符串,它们将被评估。 setTimeout需要函数,而不是字符串。
与函数::
一起使用的示例setTimeout(function(){nextW(mainE);},250);
您在脚本中提供的字符串将被评估为:
nextW(mainE)
因为setTimeout()是全局window-object的一个方法,所以这将失败,因为(在全局范围内)并不知道名为“mainE”的内容。
如果你使用字符串,它必须如下:
setTimeout("nextW('"+mainE+"')",250);
这将被评估为 nextW( 'theGivenId')
...但正如我之前所说,不要那样做。
你应该阅读关于javascript中对象和闭包的使用的一点点,它们将使你的工作更容易,正如你在galambalazs提供的例子中看到的那样。 你不需要愤怒地使用大量的全局对象和名称冲突:)