此代码在 Chrome 中运行完美,但 Firefox 表示函数 tile1
未定义。可能是什么问题?
还有,有什么办法可以缩短这个函数吗?我曾尝试在 tile1
中使用 for 循环以及 if-else
语句,但我没有成功。
$('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其中有一个关于函数语句与函数表达式的重要部分,并指出:
Functions can be conditionally defined using either //function statements// (an allowed extension to the ECMA-262 Edition 3 standard) or the Function constructor. Please note that such function statements are no longer allowed in ES5 strict. Additionally, this feature does not work consistently cross-browser, so you should not rely on it.
您看到使用此代码的浏览器之间存在差异这一事实不足为奇。
尝试
var tile1 = function () {
...
}
虽然这在这里应该对您有用,但这样做只是因为变量定义为 var
被吊起。随着 JavaScript 的发展,我们开始使用 let
而不是 var
, 您使用 tile1
在setInterval
在 tile1
的循环外调用已定义将不起作用。
可能出现的问题之一是,当您使用 i
时在内部函数中,您总是指的是 i
的单个实例在外部范围(循环计数器)中,其值始终等于 index
. (编辑:我在下面展示了如何解决这个问题。)
在循环内定义函数时要非常非常小心。您确实需要了解闭包和提升以及相关概念。有什么办法可以tile1
可以全局定义,在循环外?
关于您关于简化代码结构的问题,我认为您可以定义 tile1
与 var
, 但我认为您不需要 i
的内部循环.尝试:
$('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);
});
我不确定内部循环为您带来了什么。
旁白: future 的 JavaScript 版本正在努力处理 block 作用域中的函数语句;你可以看到here某些版本的 Chrome 支持此功能,但 Firefox 不支持。
附录
好的,现在我看到您想在 tile1
中循环三个步骤功能。虽然可以在函数内放置一个 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 处执行您想要的操作后,您将安排下一帧在 3 秒后运行,i = 1。然后大约三秒稍后使用 2,然后大约三秒后使用 0。
这里有一点偏差,所以你可能想使用 setInterval
.这需要关闭。解决方案的形式是这样的:
(function () {
var i = 0;
var tile1 = function () {
.
.
// use the value i here as needed
.
.
i = (i + 1) % 3;
};
setInterval(tile1, 3000);
}());
这段代码很酷。它是调用一个匿名函数的调用 setInterval
安排 tile1
函数每 3 秒运行一次。每次tile1
运行它使用非本地的值 i
它通过闭包从其余代码中隐藏起来。每次执行 tile1
使用 i
的正确值, 然后通过更改 i
完成为下一次调用设置正确的值!
这两种技术在 JavaScript 中都非常适合掌握。和他们一起玩吧。第二个,当然,没有时钟漂移,所以它可能更好。要使代码特化,您可能需要分配 setInterval
的结果到一个变量,这样你就可以调用clearInterval
稍后。
关于javascript - 函数在 Chrome 中运行但在 Firefox 中不运行说函数未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17227831/