带有淡入淡出动画的幻灯片



如何调整此代码,使其不会立即淡出?换句话说,让图像淡入,静置几秒钟,然后淡出?

这是我现在的代码:

<div id="slideshow-example" data-component="slideshow">
<div role="list">
<div class="slide fade">
<img src="https://images.unsplash.com/photo-1486312338219-ce68d2c6f44d?w=752&ixid=dW5zcGxhc2guY29tOzs7Ozs%3D" alt="">
</div>
<div class="slide fade">
<img src="https://images.unsplash.com/photo-1488590528505-98d2b5aba04b?w=750&ixid=dW5zcGxhc2guY29tOzs7Ozs%3D" alt="">
</div>
<div class="slide fade">
<img src="https://images.unsplash.com/photo-1498753427761-548428edfa67?w=889&ixid=dW5zcGxhc2guY29tOzs7Ozs%3D" alt="">
</div>
</div>
</div>
[data-component="slideshow"] .slide {
display: none;
text-align: center;
}
[data-component="slideshow"] .slide.active {
display: block;
}
.fade
{
-webkit-animation: fadeinout 2s linear forwards;
animation: fadeinout 2s linear forwards;
}
@-webkit-keyframes fadeinout {
0%,100% { opacity: 0; }
50% { opacity: 1; }
}

@keyframes fadeinout {
0%,100% { opacity: 0; }
50% { opacity: 1; }
}

var slideshows = document.querySelectorAll('[data-component="slideshow"]');
slideshows.forEach(initSlideShow);
function initSlideShow(slideshow) {
var slides = document.querySelectorAll(`#${slideshow.id} [role="list"] .slide`);
var index = 0, time = 5000;
slides[index].classList.add('active');
setInterval( () => {
slides[index].classList.remove('active');

index++;
if (index === slides.length) index = 0;
slides[index].classList.add('active');
}, time);
}

请忽略这一部分,StackOverflow不会让我发布,因为它是"大部分代码";尽管我对我的问题没有更多的解释。然而,如果你对我的问题感到困惑,请问我,我会尝试更深入地解释。

您可以更改元素显示的百分比,如下所示:

var slideshows = document.querySelectorAll('[data-component="slideshow"]');
slideshows.forEach(initSlideShow);
function initSlideShow(slideshow) {
var slides = document.querySelectorAll(`#${slideshow.id} [role="list"] .slide`);
var index = 0, time = 5000;
slides[index].classList.add('active');
setInterval( () => {
slides[index].classList.remove('active');

index++;
if (index === slides.length) index = 0;
slides[index].classList.add('active');
}, time);
}
[data-component="slideshow"] .slide {
display: none;
text-align: center;
}
[data-component="slideshow"] .slide.active {
display: block;
}
.fade
{
-webkit-animation: fadeinout 3s linear forwards;
animation: fadeinout 2s linear forwards;
}
@-webkit-keyframes fadeinout {
0%,100% { opacity: 0; }
20%, 80% { opacity: 1; }
}

@keyframes fadeinout {
0%,100% { opacity: 0; }
20%,50% { opacity: 1; }
}
<div id="slideshow-example" data-component="slideshow">
<div role="list">
<div class="slide fade">
<img src="https://images.unsplash.com/photo-1486312338219-ce68d2c6f44d?w=752&ixid=dW5zcGxhc2guY29tOzs7Ozs%3D" alt="">
</div>
<div class="slide fade">
<img src="https://images.unsplash.com/photo-1488590528505-98d2b5aba04b?w=750&ixid=dW5zcGxhc2guY29tOzs7Ozs%3D" alt="">
</div>
<div class="slide fade">
<img src="https://images.unsplash.com/photo-1498753427761-548428edfa67?w=889&ixid=dW5zcGxhc2guY29tOzs7Ozs%3D" alt="">
</div>
</div>
</div>

以下是使用异步等待语法和一些不同逻辑对项目的简短重写。

首先,我使用了两个辅助函数。一个是签名$函数,类似于jQuery,但只是为了缩短从文档中获取内容的时间。我还允许传递另一个元素作为我们从中选择东西的父元素,因为我觉得这会使代码更可读。另一个是类似于Python的sleep的wait函数。有更好的资源来理解promise,但简而言之,任何被称为async function的函数都将允许await关键字";等待";承诺要解决。

接下来,我使用一个传递的匿名箭头函数,它调用函数,而不仅仅是传递函数的名称。我这样做的原因是明确说明我要将forEach方法中的哪些参数传递到函数中。如果我们不这样做,第二个参数slides将被传递一个不想要的索引。

在函数initSlideShow中,我们检查是否定义了slides,如果没有,我们定义它。这样,我们就不必在每次迭代中使用查询选择器来获取内容,而是可以在递归调用中重用以前的值。

我们设置了稍后使用的时间

我们开始循环浏览每张幻灯片,并首先添加active,这将把显示更改为块。我们需要允许dom在淡入之前呈现更改,所以我们等待10ms。然后我们删除fade类,该类删除了不透明度0,而转换css使其淡入超过1s。

我们等待指定的时间。

我们将fade类添加回元素中。

我们等待动画时间我们移除active,它将display设置为none。

在我们循环浏览完所有幻灯片后,我们只需再次调用函数,传递我们已经获取的幻灯片,即可再次执行此操作。一个很好的小递归逻辑,可以永远循环函数。

如果您对代码有任何疑问,请咨询。

const $ = (str, dom = document) => [...dom.querySelectorAll(str)];
const wait = t => new Promise(r => setTimeout(r, t));
const slideshows = $('[data-component="slideshow"]');
slideshows.forEach(el => initSlideShow(el));
async function initSlideShow(container, slides) {
if (slides == undefined) slides = $('[role="list"] .slide', container);
const time = 5000;

for (const slide of slides) {
slide.classList.add("active");
await wait(10);
slide.classList.remove("fade");
await wait(time);
slide.classList.add("fade");
await wait(1000);
slide.classList.remove("active");
}
initSlideShow(container, slides);
}
[data-component="slideshow"] .slide {
display: none;
text-align: center;
transition: opacity 1s;
}
[data-component="slideshow"] .slide.active {
display: block;
}
.fade {
opacity: 0;
}
<div id="slideshow-example" data-component="slideshow">
<div role="list">
<div class="slide fade">
<img src="https://images.unsplash.com/photo-1486312338219-ce68d2c6f44d?w=752&ixid=dW5zcGxhc2guY29tOzs7Ozs%3D" alt="">
</div>
<div class="slide fade">
<img src="https://images.unsplash.com/photo-1488590528505-98d2b5aba04b?w=750&ixid=dW5zcGxhc2guY29tOzs7Ozs%3D" alt="">
</div>
<div class="slide fade">
<img src="https://images.unsplash.com/photo-1498753427761-548428edfa67?w=889&ixid=dW5zcGxhc2guY29tOzs7Ozs%3D" alt="">
</div>
</div>
</div>

不过,在实际的生产应用程序中,我会做很多不同的事情。像这样频繁地将display none更改为block可能会使页面的布局变得不可预测。我会坚持主要改变不透明度和过渡。可能在淡出时将元素滑入具有隐藏溢出的容器中。

最新更新