setInterval 后循环回开始

Loop back to start after setInterval

我有一个包含图像的列表,我想做的是每秒显示一个图像(同时显示之前的图像),然后在显示所有图像后 - 隐藏所有图像,然后重新开始该过程.我已经设法使用 setInterval 创建了我想要的效果,但我不知道如何隐藏所有内容并重新开始,而且列表中的图像数量会有所不同,因此数量未知。

这是我目前所拥有的

         <ul id="slider">
            <li><img src="images/image1.jpg" width="300px"/></li>
            <li><img src="images/image2.jpg" width="200px"/></li>
            <li><img src="images/image3.jpg" width="100px"/></li>
            <li><img src="images/image1.jpg" width="50px"/></li>
            <li><img src="images/image2.jpg" width="20px"/></li>

        </ul>

        $(document).ready(function () {


        /*Slider*/
        var slides = $("#slider > li > img");
        $(slides).hide();
        $(slides).parents("#slider>li:nth-child(1)").find("img").show();

        var x = 1;
        setInterval(function () {

            $(slides).parents("#slider>li:nth-child(" + x + ")").find("img").show();
            if (x == slides.length)

                x = 1;
            else

            x++;
        }, 1000);
        /*End*/           
    });

您已经具备将x重置为1的条件;使用相同的条件块来重置幻灯片的状态。然后,您可以使用几个辅助函数使事情变得不那么重复:

$(document).ready(function() {
  var slides = $("#slider > li > img");
  function showImage(x) {
    $(slides)
      .parents("#slider>li:nth-child(" + x + ")")
      .find("img")
      .show();
  }
  var x;
  function reset() {
    x = 1;
    $(slides).hide();
    showImage(1);
  }
  reset();

  setInterval(function() {
    if (x > slides.length) {
      reset();
    } else {
      showImage(x);
      x++;
    }
  }, 1000);
});

创建函数并根据长度检查条件并隐藏您的图像。

$(document).ready(function() {

  /*Slider*/
  var slides = $("#slider > li > img");
  var length = slides.length;
  $(slides).hide();
  $(slides).parents("#slider>li:nth-child(1)").find("img").show();

  var x = 1;
  setInterval(function() {
    function loop() {
      $(slides).parents("#slider>li:nth-child(" + x + ")").find("img").show();
      if (x == slides.length + 1) {
        $(slides).hide();
        x = 1;
      } else

        x++;
    }
    loop();
    return loop;

  }, 1000);


  /*End*/
});
#slider > li {
  list-style: none
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="slider">
  <li><img src="images/image1.jpg" width="300px" /></li>
  <li><img src="images/image2.jpg" width="200px" /></li>
  <li><img src="images/image3.jpg" width="100px" /></li>
  <li><img src="images/image1.jpg" width="50px" /></li>
  <li><img src="images/image2.jpg" width="20px" /></li>

</ul>

最简单的解决方法是添加一个简单的:

$(slides).hide()

当您达到 slides.length 时。

我认为更直观且 "easier" 的解决方案是使用异步函数。

$(document.ready(() => {
      let slides = $('slider>li>img');
      $(slides).hide();

      // Calling loop without await causes it to run without blocking the main function
      loop(slides, 1000);
})

const loop = async (slides, duration) => {
      slides.forEach(slide => {
            $(slide).show();

            // sleep for duration ms
            await new Promise(r => setTimeout(r, duration));
      }

     // After looping through all slides, hide them
     $(slides).hide();
}

如果您想无限循环 "loop" 函数,您可以创建一个新的异步函数:

const looploop = async (slides, duration) => {
       // Using the await keyword will wait for the loop function to finish,
       // And only then will it call it again.
       // The trick here is that the waiting is in the async function scope
       // so if you were to call looploop without await in the main function
       // it wouldn't block it.
       while(true) {
             await loop(slides, duration);
       }
}

js 中的异步编程改变了您对 运行 长任务的看法,例如这个任务。它允许您以迭代方式编写非阻塞函数,使其变为 "simple" 和 "easy"。