该代码可在Chrome中完美运行,但Firefox表示未定义功能tile1
。可能是什么问题呢?
另外,有什么方法可以缩短此功能?我尝试在tile1
和if-else
语句中使用for循环,但未成功。
$('div.tile').each(function(index, element) {
for(var i=0;i<=index;i++){
var tile1=function(){
var one ="div.tile div.one";
var two =" div.tile div.two";
var three = "div.tile div.three";
if(index==0){
one="div.tile div.one";
two="div.tile div.two";
three="div.tile div.three";
} else {
one ="div.tile div.one"+index;
two ="div.tile div.two"+index;
three ="div.tile div.three"+index;
}
var $one=$(one);
var $two = $(two);
var $three=$(three);
var oneTop = $one.top;
var twoTop = $two.top;
var threeTop = $three.top;
delayRate += 3000; // delayRate 5 sec (5000) by default
$one
.delay(delayRate)
.animate({top: "-100.5%"},300,easing);
$two
.delay(delayRate)
.animate({top:"0%"},300,easing);
$three
.delay(delayRate)
.animate({top:"100.5%"},300,easing);
$one
.delay(12000)
.animate({top: "-200.5%"},300,easing);
$two
.delay(12000)
.animate({top:"-100.5%"},300,easing);
$three
.delay(12000)
.animate({top:"0"},300,easing);
$one
.delay(12000)
.animate({top: "-100.5%"},300,easing);
$two
.delay(12000)
.animate({top:"0"},300,easing);
$three
.delay(12000)
.animate({top:"100.5%"},300,easing);
$one
.delay(15000-delayRate)
.animate({top: "0"},300,easing);
$two
.delay(15000-delayRate)
.animate({top:"100.5%"},300,easing);
$three
.delay(15000-delayRate)
.animate({top:"200.5%"},300,easing);
if(i==3){
delayRate=0;
}
}
}
window.setInterval(tile1, 3000);
});
正如我所说的那样,
index
是随机出现的,如0,3,1,2,并且索引对应于4个div。 最佳答案
不鼓励在JavaScript中使用函数语句。查看Mozilla's page on function scope,其中有很多关于函数语句与函数表达式的内容,并指出:
可以使用// function语句//(ECMA-262 Edition 3标准的允许扩展)或Function构造函数有条件地定义函数。请注意,ES5 strict中不再允许此类函数语句。此外,此功能无法跨浏览器一致地工作,因此您不应依赖它。
您发现使用此代码的浏览器之间存在差异,这一事实不足为奇。
尝试
var tile1 = function () {
...
}
尽管这应该对您有用,但这仅是因为使用
var
的变量定义已被提升。随着JavaScript的发展,我们开始使用let
而不是var
,在定义tile1
的循环之外的setInterval
调用中使用tile1
无效。可能出现的问题之一是,当在内部函数中使用
i
时,总是在外部范围(循环计数器)中引用i
的单个实例,其值始终等于。 (编辑:我在下面显示了解决方法。)在循环内定义函数时,务必非常非常小心。您确实需要了解封闭和吊装以及相关概念。有什么方法可以在循环外全局定义
index
?关于简化代码结构的问题,我认为您可以使用
tile1
定义tile1
,但是我认为您不需要使用var
进行内部循环。尝试:$('div.tile').each(function(index, element) {
var tile1 = function () {
var one ="div.tile div.one";
.
.
.
if (index === 3) { // CHANGED I TO INDEX HERE.
delayRate=0;
}
}
window.setInterval(tile1, 3000);
});
我不确定内在因素在买什么。
旁白:未来的JavaScript版本正在努力在块范围内处理函数语句。您可以看到here某些版本的Chrome(但Firefox)不支持此功能。
附录
好的,现在我看到您想在
i
函数中循环执行三个步骤。尽管可以在函数内部放入for循环,但是JavaScript的方法是使函数每次仅运行动画的一个步骤。如果需要某种计数器,则该计数器应在外部。一种方法是这样的:var tile1 = function (i) {
.
.
// use the value i here as needed
.
.
setTimeout(function () {tile1((i + 1) % 3)}, 3000);
};
tile1(0);
它的作用是首先调用值为0的tile函数。然后在0处执行所需的操作后,您将安排下一帧在i = 1的3秒后运行。然后在3秒钟后的2秒运行。 ,然后三秒钟左右的时间为0。
这里有点漂移,所以您可能要使用
tile1
。这需要关闭。解决方案的形式是这样的:(function () {
var i = 0;
var tile1 = function () {
.
.
// use the value i here as needed
.
.
i = (i + 1) % 3;
};
setInterval(tile1, 3000);
}());
这段代码很酷。这是对匿名函数的调用,该函数调用
setInterval
安排setInterval
函数每3秒运行一次。每次tile1
运行时,它都会使用非本地tile1
的值,该值在带有闭包的其余代码中是隐藏的。每次执行i
使用正确的tile1
值,然后通过将i
更改为下一个调用的正确值来结束!这两种技术都可以很好地掌握JavaScript。和他们一起玩。第二个当然没有时钟漂移,所以可能会更好。为了使代码专业化,您可能希望将
i
的结果分配给变量,以便以后可以调用setInterval
。