在我的数组'bg'中,当'fadebg'函数到达时,最后一项/图像重复两次, 任何人都可以回答我为什么会发生这种情况以及如何解决这个问题?
var bg = [];
bg[0] = "resources/images/bg/1.jpg";
bg[1] = "resources/images/bg/2.jpg";
bg[2] = "resources/images/bg/3.jpg";
bg[3] = "resources/images/bg/4.jpg";
bg[4] = "resources/images/bg/5.jpg";
bg[5] = "resources/images/bg/6.jpg";
bg[6] = "resources/images/bg/7.jpg";
bg[7] = "resources/images/bg/8.jpg";
bg[8] = "resources/images/bg/9.jpg";
bg[9] = "resources/images/bg/10.jpg";
var i = 0;
setInterval(fadebg, 10000);
function fadebg() {
if (i < 10) {
$('#bg').css({ opacity: 0 });
setTimeout(function () {
$('#bg').attr('src', bg[i]).css({ opacity: 1 })
}, 300);
};
if (i == 10) {
i = -1;
$('#bg').css({ opacity: 0 });
setTimeout(function () {
$('#bg').attr('src', bg[i]).css({ opacity: 1 })
}, 300);
};
i++;
};
顺便说一句,是否有人知道这个函数'fadebg'的缩写版本?
答案 0 :(得分:3)
这是因为fadebg
内的函数靠近变量 i
,而不是创建函数时的值。他们使用运行时的值。这是经典的关闭错误。更多:Closures are not complicated。
要使用创建函数时的值,您必须使用i
以外的其他内容。我通常使用构建器函数:
function buildTheCallback(src) {
return function () {
$('#bg').attr('src', src).css({ opacity: 1 })
};
}
...你这样使用:
setTimeout(buildTheCallback(bg[i]), 300);
现在,我们给出的函数setTimeout
(调用buildTheCallback
返回的函数)会关闭我们传递给它的src
参数,但不会得到改变。
一个较短的版本,这些内容(未经测试 嘿,你知道什么,it works [我将10000毫秒缩短到1000毫秒进行测试] ):
(function() {
var bg = [
"resources/images/bg/1.jpg",
"resources/images/bg/2.jpg",
"resources/images/bg/3.jpg",
"resources/images/bg/4.jpg",
"resources/images/bg/5.jpg",
"resources/images/bg/6.jpg",
"resources/images/bg/7.jpg",
"resources/images/bg/8.jpg",
"resources/images/bg/9.jpg",
"resources/images/bg/10.jpg"
];
var bgIndex = -1;
setInterval(fadeBg, 10000);
function fadeBg() {
bgIndex = (bgIndex + 1) % bg.length;
$('#bg').css({ opacity: 0 });
setTimeout(showBg, 300);
}
function showBg() {
$('#bg').attr('src', bg[bgIndex]).css({ opacity: 1 })
}
})();
(我假设除了数字之外,图像的真实路径不相同;如果是,则可以使其明显缩短。)
但如果是我,我会褪色而不是突然转向opacity: 0
/ opacity: 1
:Live Example
(function() {
var bg = [
"resources/images/bg/1.jpg",
"resources/images/bg/2.jpg",
"resources/images/bg/3.jpg",
"resources/images/bg/4.jpg",
"resources/images/bg/5.jpg",
"resources/images/bg/6.jpg",
"resources/images/bg/7.jpg",
"resources/images/bg/8.jpg",
"resources/images/bg/9.jpg",
"resources/images/bg/10.jpg"
];
var bgIndex = -1;
setInterval(fadeBg, 10000);
function fadeBg() {
bgIndex = (bgIndex + 1) % bg.length;
$('#bg').fadeTo("300", 0, showBg);
}
function showBg() {
$('#bg').attr('src', bg[bgIndex]).fadeTo("300", 1);
}
})();
答案 1 :(得分:3)
这是一个更简单的版本:
(function() {
var bgIndex = 0;
setInterval(function() {
var item = $('#bg').css({ opacity: 0 });
setTimeout(function() {
item.attr("src", bg[++bgIndex % bg.length]);
}, 300);
}, 10000);
})();
它使用%
技巧允许索引循环遍历数组,而不会离开数组的边界。
此外,这解决了您遇到的原始问题,因为索引变量仅在您使用索引时才会递增,因此在变量增加和使用时没有时间延迟问题。
增强功能摘要:
% bl.length
技巧简化代码以保持在数组的范围内,并将您的两个代码分支折叠为仅一个分支。i
是一种非常危险的做法。在var
循环中忘记for (i = 0;...)
的一行代码,现在您的全局i
会被删除。$('#bg')
的价值,这样您就不会在短时间内重新开始。答案 2 :(得分:2)
尝试:
function fadebg() {
if( i == 10 ){
i = -1;
}
$('#bg').css({ opacity: 0 });
setTimeout(function () {
$('#bg').attr('src', bg[i]).css({ opacity: 1 })
}, 300);
i++;
};
答案 3 :(得分:0)
你可以做这样的事情来缩小你的功能:
bg.each(function(i){
$('#bg').css({opacity:0});
setTimeout(function () {
$('#bg').attr('src', bg[i]).css({ opacity: 1 })
}, 300);
});
我还没有测试过,但可能需要考虑一下。