我正在尝试创建非JQuery图像幻灯片,其中图像根据计时器淡入/淡出。经过大量研究,我相信JavaScript的Promise功能可以做到这一点,但这并不完全正确。
我的问题是淡入和淡出功能似乎是同时发生的,因此图像只是闪烁。我正在尝试改编使用then()
链接函数的许多示例,但是显然有些错误。
我的逻辑是:
我的online example is here,JavaScript在这里:
// Background images to show
var arr_Images = [
'https://cdn.pixabay.com/photo/2015/08/24/12/53/banner-904884_960_720.jpg',
'https://cdn.pixabay.com/photo/2016/11/19/22/52/coding-1841550_960_720.jpg',
'https://cdn.pixabay.com/photo/2014/05/27/23/32/matrix-356024_960_720.jpg'
];
var cycleImage = document.getElementById("cycleImage");
// Preload images
for(x = 0; x < arr_Images.length; x++)
{
var img = new Image();
img.src = arr_Images[x];
}
function fadeOutPromise(element, nextBgImgUrl) {
console.log("Fading out");
return new Promise(function(resolve) {
var op = 1; // initial opacity
var timer1 = setInterval(function () {
if (op <= 0.1){
clearInterval(timer1);
element.style.display = 'none';
cycleImage.style.backgroundImage = "url('" + nextBgImgUrl + "')";
}
element.style.opacity = op;
element.style.filter = 'alpha(opacity=' + op * 100 + ")";
op -= op * 0.1;
}, 100);
resolve("Faded In");
});
}
function fadeInPromise(element) {
console.log("Fading in");
return new Promise(function(resolve) {
var op = 0.1; // initial opacity
element.style.display = 'block';
var timer2 = setInterval(function () {
if (op >= 1){
clearInterval(timer2);
}
element.style.opacity = op;
element.style.filter = 'alpha(opacity=' + op * 100 + ")";
op += op * 0.1;
}, 10);
resolve("Faded Out");
});
}
function slideShow() {
// Loop background image using array
var i = 0;
var delay = 3000;
// Loop
let imageLoopTimer = setTimeout(function tick() {
fadeOutPromise(cycleImage, arr_Images[i]).then(
fadeInPromise(cycleImage).then(function() {
i++;
if ( i >= arr_Images.length) { i = 0; }
imageLoopTimer = setTimeout(tick, delay);
})
);
}, delay);
}
slideShow();
有人可以先解释出什么问题,然后提供解决方案吗?
答案 0 :(得分:3)
您快到了。问题是您如何履行诺言。
您打算在淡入淡出功能中执行的操作是:
-创造承诺
-间隔执行逻辑
-兑现诺言
但是您可以立即解决承诺,而一旦完成淡入淡出操作,就应该解决承诺:
function fadeInPromise(element) {
console.log("Fading in");
return new Promise(function(resolve) {
var op = 0.1; // initial opacity
element.style.display = 'block';
var timer2 = setInterval(function () {
if (op >= 1){
clearInterval(timer2);
resolve(): // Fade is done here
}
element.style.opacity = op;
element.style.filter = 'alpha(opacity=' + op * 100 + ")";
op += op * 0.1;
}, 10);
});
}
淡入淡出
另一个闪烁的提示
如果要获得平滑效果,则不应经常更改不透明度。在CSS中,已经有“ transition”属性。因此,您应该在过渡时执行以下操作:
-显示不透明度为1的图像
-将opactiy设置为0
-ms之后,更改网址并将不透明度设置为1
答案 1 :(得分:1)
setInterval()
作为后台任务运行,因此resolve()
将在timer2
初始化后立即被触发。
async
操作非常相似,但与awaiting
不同
它。function
返回一个Promise
一样,但是想要访问数据而没有.then()
回调您需要在if (op >= 1)
部分内解决您的承诺,以便在发生淡入/淡出后实际解决该承诺。
检查this snippet中您的更新版本。承诺在setInterval()
内部解决。
以下是直接代码段的相关JavaScript代码:
function fadeOutPromise(element, nextBgImgUrl) {
console.log("Fading out"+i);
return new Promise(function(resolve, reject) {
element.style.opacity = 0;
setTimeout(() => {
console.log("Fading out done"+i);
element.style.backgroundImage = "url('" + nextBgImgUrl + "')";
resolve();
}, 1000);
});
}
function fadeInPromise(element) {
console.log("Fading in"+i);
return new Promise(function(resolve, reject) {
element.style.opacity = 1;
setTimeout(resolve, 1000);
});
}
var i = 0;
var delay = 3000;
function slideShow() {
// Loop background image using array
// Loop
let imageLoopTimer = setTimeout(() => tick(), delay);
}
function tick() {
fadeOutPromise(cycleImage, arr_Images[i]).then(() =>
fadeInPromise(cycleImage).then(function() {
i++;
if ( i >= arr_Images.length) { i = 0; }
imageLoopTimer = setTimeout(() => tick(), delay);
})
);
}
我有edited the snippet,现在可以在不透明的情况下进行过渡了。