【问题标题】:How to run setTimeOut infinite times?如何无限次运行 setTimeOut?
【发布时间】:2019-08-18 11:58:41
【问题描述】:

我已经广泛搜索了相同的解决方案,但没有一个解决方案有效,所以在这里询问

我想在循环中更改背景图像[基本上更改元素的类]。但对我(JavaScript 新手)来说真正棘手的部分是 setTimeOut 在固定次数后停止。代码如下:

function addHomeInnerClass(selector, imageNumber = 0) {

imageNumber += 1;
  if (imageNumber === 1) {
    selector.classList.add('home-content-1');
  }

  if (imageNumber === 2) {
    selector.classList.add('home-content-2');
  }

  if (imageNumber === 3) {
    selector.classList.add('home-content-3');
  }

  if (imageNumber === 4) {
    selector.classList.add('home-content-4');
    imageNumber = 0;
  }

  setTimeout(() => addHomeInnerClass(selector, imageNumber), 1000);
}

document.addEventListener('DOMContentLoaded', function() {
  const homeInner = document.querySelector('.home-inner');

  addHomeInnerClass(homeInner, 0);

});

这是我的 HTML 部分:

<section class="home" id="home">
    <div class="home-inner">

    </div>
</section>

这是我的 CSS3:

.home {
    background-image: linear-gradient(to right, #ff5517 0%, #ff7000 40%, #db1d5e 80%);
    height: 88.98vh;

    .home-content-1 {
      height: 98%;
      border-bottom-right-radius: 20rem;
      background: linear-gradient(to right, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0.3) 40%, rgba(0, 0, 0, 0.9) 80%), url("/app/assets/images/slider/ (2).jpg") no-repeat center center/cover;
      z-index: 1;
    }

    .home-content-2 {
      height: 98%;
      border-bottom-right-radius: 20rem;
      background: linear-gradient(to right, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0.3) 40%, rgba(0, 0, 0, 0.9) 80%), url("/app/assets/images/slider/ (3).jpg") no-repeat center center/cover;
      z-index: 1;
    }

    .home-content-3 {
      height: 98%;
      border-bottom-right-radius: 20rem;
      background: linear-gradient(to right, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0.3) 40%, rgba(0, 0, 0, 0.9) 80%), url("/app/assets/images/slider/(4).jpg") no-repeat center center/cover;
      z-index: 1;
    }

    .home-content-4 {
      height: 98%;
      border-bottom-right-radius: 20rem;
      background: linear-gradient(to right, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0.3) 40%, rgba(0, 0, 0, 0.9) 80%), url("/app/assets/images/slider/ (1).jpg") no-repeat center center/cover;
      z-index: 1;
    }
  }

我知道 CSS 和 HTML 代码在这里几乎不重要,但如果我能找到其他方法来做我想做的事,那就太好了。

我想做什么? 使用纯 javascript 来获得淡入淡出的图像效果。

我卡在哪里了? 不知道如何无限次运行 setTimeOut?

注意:我不想使用任何第三方库。这是一个学习项目。

【问题讨论】:

  • setTimeout() 运行一次回调。 setInterval() 运行回调,直到您明确取消它。
  • 我应该在哪里使用 setInterval?
  • 看看用setInterval() 替换setTimeout() 是否符合您的要求。
  • 这个问题和PHP有什么关系?
  • 您正在从计时器调用的函数中安排下一个计时器回调,这不会停止 "...在固定次数之后。" 但我请注意,您只是添加类。添加下一个时,您可能希望删除前一个。我怀疑一旦你绕回,即使计时器循环确实继续,你也看不到变化了。

标签: javascript html css


【解决方案1】:

正如我said in a comment,问题不在于计时器停止运行。当您添加新课程时,您并没有删除旧课程。在简化代码的同时,您可以这样做:

function addHomeInnerClass(selector, imageNumber = 0) {

  selector.classList.remove('home-content-' + imageNumber);
  imageNumber = imageNumber % 4 + 1;
  selector.classList.add('home-content-' + imageNumber);

  setTimeout(() => addHomeInnerClass(selector, imageNumber), 1000);
}

实时示例(我稍微修改了 CSS 以便于查看更改;我还在 .home 规则之后添加了缺少的 }):

function addHomeInnerClass(selector, imageNumber = 0) {

  selector.classList.remove('home-content-' + imageNumber);
  imageNumber = imageNumber % 4 + 1;
  selector.classList.add('home-content-' + imageNumber);

  setTimeout(() => addHomeInnerClass(selector, imageNumber), 1000);
}

document.addEventListener('DOMContentLoaded', function() {
  const homeInner = document.querySelector('.home-inner');

  addHomeInnerClass(homeInner, 0);

});
.home {
    height: 88.98vh;
}
    .home-content-1 {
      height: 98%;
      border-bottom-right-radius: 20rem;
      background: url("https://via.placeholder.com/100/0000C0/FFFFFF?text=1") no-repeat center center/cover;
      z-index: 1;
    }

    .home-content-2 {
      height: 98%;
      border-bottom-right-radius: 20rem;
      background: url("https://via.placeholder.com/100/0000C0/FFFFFF?text=2") no-repeat center center/cover;
      z-index: 1;
    }

    .home-content-3 {
      height: 98%;
      border-bottom-right-radius: 20rem;
      background: url("https://via.placeholder.com/100/0000C0/FFFFFF?text=3") no-repeat center center/cover;
      z-index: 1;
    }

    .home-content-4 {
      height: 98%;
      border-bottom-right-radius: 20rem;
      background:  url("https://via.placeholder.com/100/0000C0/FFFFFF?text=4") no-repeat center center/cover;
      z-index: 1;
    }
  }
<section class="home" id="home">
    <div class="home-inner">

    </div>
</section>

【讨论】:

    【解决方案2】:

    根据 cmets 中的建议,setInterval is exactly tailored 满足您的需求。它允许您每 x 毫秒运行一个函数(例如 addHomeInnerClass 在您的情况下)。但是请注意,使用此功能需要您稍微更改您的imageNumber 逻辑。 此外,正如 cmets 中所述,您应该在添加新类之前删除旧类。

    我会建议以下方法:

    let imageNumber = 0;
    function addHomeInnerClass(selector) {
      selector.classList.remove('home-content-' + imageNumber);
      imageNumber++;
      if(imageNumber === 5) imageNumber = 1;
      selector.classList.add('home-content-' + imageNumber);
    }
    
    document.addEventListener('DOMContentLoaded', function() {
      const homeInner = document.querySelector('.home-inner');
    
      setInterval(() => addHomeInnerClass(homeInner), 1000);
    });
    
    

    【讨论】:

    • 试过你的解决方案,它也可以。但我想我会选择@T.J。 Crowder 的解决方案表明 setTimeOut 不是真正的问题。谢谢。
    猜你喜欢
    • 2020-11-24
    • 1970-01-01
    • 2021-12-13
    • 2011-12-13
    • 2017-01-24
    • 1970-01-01
    • 2016-12-05
    • 2014-09-28
    • 1970-01-01
    相关资源
    最近更新 更多