自定义jquery图像滑块中的setInterval问题同时包含自动幻灯片和按钮

时间:2018-04-22 12:04:18

标签: javascript jquery html css

我正在jQuery中创建一个带有自定义幻灯片效果的自定义图像滑块,它具有next和amp;以前的按钮,并自动滑动5秒超时。虽然它很快就可以快速查看但有时候(我不知道确切的时间,也许当我按下按钮或者我将它打开一段时间并最小化窗口时)iterval错误和幻灯片在1秒或更短时间后会发生变化。此外,当我按下按钮我告诉它1)清除iterval 2)更改幻灯片3)再次设置间隔,这意味着我用按钮更改幻灯片后,计时器从开始设置为5秒,但这不会发生所有时间。这是代码。

$(document).ready(function() {

  'use strict';

  var $carousel = $('.carousel');
  var $nextBtn = $('#next');
  var $prevBtn = $('#prev');
  var animationSpeed = 1000;
  var pause = 5000;
  var interval;


  function nextSlide() {
    $('.carousel__list').animate({
      left: '-200%'
    }, 500, function() {

      $('.carousel__list').css('left', '-100%');

      $('.carousel__item').last().after($('.carousel__item').first());

    });
  }


  function prevSlide() {
    $('.carousel__list').animate({
      left: '0%'
    }, 400, function() {

      $('.carousel__list').css('left', '-100%');

      $('.carousel__item').first().before($('.carousel__item').last());

    });
  }


  function startSlider() {
    interval = setInterval(function() {
      nextSlide();
    }, pause);
  }


  function stopSlider() {
    clearInterval(interval);
  }


  $carousel.on('mouseenter', stopSlider).on('mouseleave', startSlider);

  startSlider();

  $nextBtn.on('click', function() {
    stopSlider();

    nextSlide();

    startSlider();

  });

  $prevBtn.on('click', function() {
    stopSlider();

    prevSlide();

    startSlider();
  });

});
*,
*::after,
*::before {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.carousel {
  width: 100%;
  height: 65vh;
  overflow: hidden;
  position: relative;
}

.carousel__list {
  width: 400%;
  height: 100%;
  left: -100%;
  position: relative;
  list-style: none;
}

.carousel__item {
  width: calc(100% / 4);
  height: 100%;
  float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="carousel">
  <ul class="carousel__list">
    <li class="carousel__item" style="background-color: red"></li>
    <li class="carousel__item" style="background-color: green"></li>
    <li class="carousel__item" style="background-color: blue"></li>
    <li class="carousel__item" style="background-color: yellow"></li>
  </ul>
</section>
<button id="prev">PREVIOUS</button>
<button id="next">NEXT</button>

这是一个代码:https://codepen.io/anon/pen/erpyJj

1 个答案:

答案 0 :(得分:1)

您创建的间隔比您想象的要多,并且实际上并没有清除每个间隔,因为您覆盖了interval变量,然后您没有引用之前的间隔,这些间隔可能仍处于活动状态

你能做的就是把你创建的每个间隔都放在一个数组中,然后当你需要停止所有的间隔时,遍历那个数组,清除每个间隔并清空数组。

// ...
var intervals = [];
// ... 

function stopSlider() {
    console.log("stopSlider() intervals (Before clear): ", intervals);
    intervals.forEach(function(interval) {
        clearInterval(interval); // stop one interval
    });
    intervals = []; // clear the array
    console.log("stopSlider() intervals (After clear): ", intervals);
}

以下是包含许多控制台日志的演示。您可以看到,无论您点击任何按钮多少都没关系,滑块每5秒自动滑动一次。

$(document).ready(function() {
  "use strict";

  //cache dom elements
  var $carousel = $(".carousel");
  var $nextBtn = $("#next");
  var $prevBtn = $("#prev");
  var animationSpeed = 1000;
  var pause = 5000;
  var intervals = [];

  function nextSlide() {
    console.log("nextSlide() intervals: ", intervals);
    $(".carousel__list").animate({
      left: "-200%"
    }, 500, function() {
      $(".carousel__list").css("left", "-100%");

      $(".carousel__item")
        .last()
        .after($(".carousel__item").first());
    });
  }

  function prevSlide() {
    console.log("prevSlide() intervals: ", intervals);
    $(".carousel__list").animate({
      left: "0%"
    }, 400, function() {
      $(".carousel__list").css("left", "-100%");

      $(".carousel__item")
        .first()
        .before($(".carousel__item").last());
    });
  }

  function startSlider() {
    console.log("startSlider() interval (BEFORE): ", intervals);
    var interval = setInterval(function() {
      nextSlide();
    }, pause);
    intervals.push(interval);
    console.log("startSlider() interval (AFTER): ", intervals);
  }

  function stopSlider() {
    console.log("stopSlider() intervals (Before clear): ", intervals);
    intervals.forEach(function(interval) {
      clearInterval(interval); // stop one interval
    });
    intervals = []; // clear the array
    console.log("stopSlider() intervals (After clear): ", intervals);
  }

  $carousel.on("mouseenter", stopSlider).on("mouseleave", startSlider);

  startSlider();

  $nextBtn.on("click", function() {
    stopSlider();

    nextSlide();

    startSlider();
  });

  $prevBtn.on("click", function() {
    stopSlider();

    prevSlide();

    startSlider();
  });
});
*,
*::after,
*::before {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.carousel {
  width: 100%;
  height: 20vh;
  overflow: hidden;
  position: relative;
}

.carousel__list {
  width: 400%;
  height: 100%;
  left: -100%;
  position: relative;
  list-style: none;
}

.carousel__item {
  width: calc(100% / 4);
  height: 100%;
  float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="carousel">

  <ul class="carousel__list">
    <li class="carousel__item" style="background-color: red"></li>
    <li class="carousel__item" style="background-color: green"></li>
    <li class="carousel__item" style="background-color: blue"></li>
    <li class="carousel__item" style="background-color: yellow"></li>
  </ul>

</section>

<button id="prev">PREVIOUS</button>
<button id="next">NEXT</button>