【问题标题】:Slideshow with fade animation带有淡入淡出动画的幻灯片
【发布时间】:2022-01-25 09:09:24
【问题描述】:

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

这是我现在的代码:

    <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 不会让我发布,因为它“主要是代码”,即使我无法对我的问题给出更多解释。但是,如果您对我的问题感到困惑,请问我,我会尝试更深入地解释它。

【问题讨论】:

  • 我建议使用transition 属性而不是动画,并使用js async await 语法通过const wait = time =&gt; new Promise(resolve =&gt; setTimeout(resolve, time)); 之类的辅助函数来控制延迟/时间流,我可以提供更多详细信息如果当前答案不满足您的用例,则稍后再做。
  • 我应该把它放在我的代码中的什么地方?
  • 我为你添加了一个答案,如果你想要一个例子????

标签: javascript html css


【解决方案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);
}
[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>

【讨论】:

  • 如果您希望图像停留更长时间或希望避免显示空白背景的时间,您可以增加动画的持续时间以匹配 setTimeout 中使用的时间
【解决方案2】:

这里是使用 async await 语法和一些不同的逻辑对您的项目进行的简短重写。

首先,我使用了两个辅助函数。一个是签名$ 函数,类似于 jQuery,但只是为了缩短从文档中抓取内容。我还允许将另一个元素作为我们从中选择内容的父元素传递,因为我觉得它使代码更具可读性。另一个是waitfunction similar to Python's sleep。有更好的资源来理解 Promise,但简而言之,任何称为 async function 的函数都将允许 await 关键字“等待”解决 Promise。

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

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

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

我们开始循环播放每张幻灯片,首先添加active,这会将显示更改为阻止。我们需要让 dom 在淡入之前渲染变化,所以我们等待 10 毫秒。然后我们移除 fade 类,该类移除不透明度 0,并且过渡 css 使其淡入淡出超过 1 秒。

我们等待指定的时间。

我们将淡入淡出类添加回元素。

我们等待动画时间 我们移除 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 可能会使页面的布局发生不可预测的变化。我会坚持主要改变不透明度和过渡。淡出时,可能会在隐藏溢出的容器内滑动元素。

【讨论】:

    猜你喜欢
    • 2014-09-25
    • 2023-03-25
    • 1970-01-01
    • 2012-12-09
    • 2018-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多