Javascript click event is doubling every click

4211 views javascript
0

Would be really grateful for some advice with this javascript issue I am having with a click event that seems to be doubling every time my slider is closed then reopened.

When you open the slider for the first time and click through the slides you can see in the console the clicks incrementing by 1 every time the 'btn--next' is clicked which is of course correct. When i then close the slider down and re-open it again when the 'btn--next' is clicked the clicks in the console are now incrementing by 2 every click. Close the slider again and re-open and then the 'btn--next' clicks in the console increment by 3 and so on every time the slider is re-loaded. https://jsfiddle.net/95afhtx8/2/

 var loadSlider = document.querySelector('.load__slider');


loadSlider.addEventListener('click', function() {

  var slider = document.querySelector('.animal__slider');
  var sliderSlide = document.querySelectorAll('.animal__slider__slide');
  var nextSlide = document.querySelector('.btn--next');
  var previousSlide = document.querySelector('.btn--previous');
  var closeSlider = document.querySelector('.animal__slider__close');
  var currentSlide = 0;

  slider.classList.add('active');
  setTimeout(function() {
    slider.classList.add('active--show');
    startSlide();
  }, 100);

  //Reset Slider
  function resetSlides() {
    for (var s = 0; s < sliderSlide.length; s++) {
      sliderSlide[s].classList.remove('active--show');
      sliderSlide[s].classList.remove('active');
    }
  }

  //Start Slider
  function startSlide() {
    resetSlides();
    sliderSlide[0].classList.add('active');
    setTimeout(function() {
      sliderSlide[0].classList.add('active--show');
    }, 100);
  }

  //Previous slide
  function slidePrevious() {
    resetSlides();
    sliderSlide[currentSlide - 1].classList.add('active');
    setTimeout(function() {
      sliderSlide[currentSlide].classList.add('active--show');
    }, 100);
    currentSlide--;
  }

  previousSlide.addEventListener('click', function() {
    if (currentSlide === 0) {
      currentSlide = sliderSlide.length;
    }
    console.log('click');
    slidePrevious();
  });

  //Next slide
  function slideNext() {
    resetSlides();
    sliderSlide[currentSlide + 1].classList.add('active');
    setTimeout(function() {
      sliderSlide[currentSlide].classList.add('active--show');
    }, 100);
    currentSlide++;
  }

  nextSlide.addEventListener('click', function() {
    if (currentSlide === sliderSlide.length - 1) {
      currentSlide = -1;
    }
    console.log('click');
    slideNext();
  });

  closeSlider.addEventListener('click', function() {
    slider.classList.remove('active--show');
    slider.classList.remove('active');
    resetSlides();
  });
});

answered question

You're accumulating event listeners every time you open the slider...

1 Answer

12

It's because every time you click on your slider toggle:

loadSlider[s].addEventListener('click', function () { 

You're re-running code like this, which will add another click handler to the element:

 nextSlide.addEventListener('click', function() {

You can add multiple event listeners to any object in the DOM. So you just keep adding more every time the slider opens.

You have three general options here.

Option 1: only set click handlers once

Don't re-add event handlers inside your loadSlider[s].addEventListener('click', function () { function. Do it outside so you aren't re-adding handlers.

Option 2: remove click handlers on close

You can remove the event listeners on close. To do this, you should store a reference to the function you make, so you can explicitly remove it later. You should do this for any handlers you add.

const nextClick = function () {
    ...
};
nextSlide.addEventListener('click', nextClick);

function resetSlides() {
    nextSlide.removeEventListener('click', nextClick);
    ...
}

This way, when the slider is hidden, the click functionality will be turned off, and re-opening it will add new click handlers and the old ones won't fire because you removed them.

Option 3: Re-create the elements

If you remove an element from the DOM and make a completely new one, the new one won't have stale click handlers on it. This means you'll need to dynamically build your markup with Javascript (using document.createElement), not store it in the HTML page body.

posted this

Have an answer?

JD

Please login first before posting an answer.