Slider Not Sliding More Than One Iteration Each Way (JavaScript)

Viewed 48

I have a slider that has 4 articles on it. I can get it to slide each way by 1 article, but can't seem to get it to repeat the action on the second time of clicking the 'left' button. I'm not sure if it's the counter that is the problem or the transform value? I do need to use transform instead of left or right because I need it execute at 60fps on the animation.

Codepen: https://codepen.io/emilychews/pen/vYXJyqZ

var leftButton = document.getElementById("left-button"),
  rightButton = document.getElementById("right-button"),
  article = document.querySelectorAll(".article"),
  counter = 0,
  articleWidth = article.offsetWidth;

if (counter <=1) {
  leftButton.addEventListener("click", function () {
    article.forEach(function (item) {
      item.style.transform = "translateX(-100%)";
      item.style.transition = "all 2s";

      counter += 1;
    });
  });
}

if (counter < article.length) {
  rightButton.addEventListener("click", function () {
    article.forEach(function (item) {
      item.style.transform = "translateX(0)";
      item.style.transition = "transform 2s";

      counter -= 1;
    });
  });
}
* {
  margin: 0;
  box-sizing: border-box;
}

body {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

.row {
  width: 50%;
  background: red;
  overflow: hidden;
  margin-bottom: 2rem;
}

.article-wrapper {
  display: flex;
  width: 160%;
}

.article {
  width: 70%;
  background: blue;
  margin: 0 1rem;
  padding: 4rem 1rem;
}

p {
  color: white;
}
<div class="row">
  <div class="article-wrapper">
    <article class="article">
      <p>Article 1</p>
    </article>
    <article class="article">
      <p>Article 2</p>
    </article>
    <article class="article">
      <p>Article 3</p>
    </article>
    <article class="article">
      <p>Article 4</p>
    </article>
  </div>
</div>
<button id="left-button">Left</button>
<button id="right-button">Right</button>

1 Answers

One issue is that you only need to add the event listeners once and there's no need to condition adding event listeners off of the counter. If you use the counter approach, you can return early in the click handler when the desired criteria is met.

The next issue is that your "left" handler isn't working more than once because your transform has to be 100 * counter transformed. The following code keeps pretty close to your initial design but generally works.

var leftButton = document.getElementById("left-button"),
  rightButton = document.getElementById("right-button"),
  article = document.querySelectorAll(".article"),
  counter = 0,
  articleWidth = article.offsetWidth;


leftButton.addEventListener("click", function () {
  if (counter === article.length) return;
  counter += 1;
  article.forEach(function (item) {
    item.style.transform = `translateX(-${counter}00%)`;
    item.style.transition = "all 2s";
  });
});

rightButton.addEventListener("click", function () {
  if (counter === 0) return;
  counter -= 1;
  article.forEach(function (item) {
    item.style.transform = "translateX(0)";
    item.style.transition = "transform 2s";
  });
});
* {
  margin: 0;
  box-sizing: border-box;
}

body {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

.row {
  width: 50%;
  background: red;
  overflow: hidden;
  margin-bottom: 2rem;
}

.article-wrapper {
  display: flex;
  width: 160%;
}

.article {
  width: 70%;
  background: blue;
  margin: 0 1rem;
  padding: 4rem 1rem;
}

p {
  color: white;
}
<div class="row">
  <div class="article-wrapper">
    <article class="article">
      <p>Article 1</p>
    </article>
    <article class="article">
      <p>Article 2</p>
    </article>
    <article class="article">
      <p>Article 3</p>
    </article>
    <article class="article">
      <p>Article 4</p>
    </article>
  </div>
</div>
<button id="left-button">Left</button>
<button id="right-button">Right</button>

Related