2

Sorry for the possible duplication, but I did not find a solution to my problem. About my problem. I am trying to create a slide carousel using only js and css. What I need is an alternation of slides when we press the “forward” or “back” buttons (for example, the previous slide goes off to the left, while the new slide simultaneously appears from the right when “forward” is pressing).

The code is here:

var slideIndex = 0;
var prev_slideIndex = slideIndex;

function myanimate() {
  str = 'slideIndex=' + slideIndex + ' prev_slideIndex=' + prev_slideIndex;

  var slides = document.getElementsByClassName("child");
  for (var i = 0; i < slides.length; i++) slides[i].style.display = "none";

  if (prev_slideIndex < slideIndex) {
    if (slideIndex > 3) slideIndex = 0;
    slides[prev_slideIndex].style.left = '-100%';
    slides[prev_slideIndex].style.marginleft = '0%';
    slides[slideIndex].style.left = '0%';
    slides[slideIndex].style.marginleft = '0%';
    slides[prev_slideIndex].style.animation = slides[slideIndex].style.animation = 'caroussel 1.5s';
  } else {
    if (slideIndex < 0) slideIndex = 3;
    slides[prev_slideIndex].style.left = '100%';
    slides[prev_slideIndex].style.marginleft = '0%';
    slides[slideIndex].style.left = '0%';
    slides[slideIndex].style.marginleft = '0%';
    slides[prev_slideIndex].style.animation = slides[slideIndex].style.animation = 'caroussel_back 1.5s';
  }

  slides[prev_slideIndex].style.display = 'block';
  slides[slideIndex].style.display = 'block';
  prev_slideIndex = slideIndex;

  str += ' final prev_slideIndex=' + prev_slideIndex;
  document.getElementById("text").innerHTML = str;
}
.parent {
  background-color: red;
  display: block;
  position: relative;
  width: 600px;
  height: 100px;
  padding-top: 10px;
  padding-bottom: 10px;
  overflow: hidden;
}

.child {
  background-color: green;
  display: block;
  position: absolute;
  width: 100%;
  height: 100px;
  color: #FFFFFF;
  font-size: 24px;
  text-align: center;
}

@keyframes caroussel {
  from {
    margin-left: 100%
  }
  to {
    margin-left: 0%
  }
}

@keyframes caroussel_back {
  0% {
    margin-left: -100%
  }
  100% {
    margin-left: 0%
  }
}
<input type="submit" value='forward' title="sdg" onclick="slideIndex++;myanimate();">
<input type="submit" value='backward' title="sdg" onclick="slideIndex--;myanimate();">
<br>
<div class="parent">
  <div class="child" style="background-color:yellow;left:0%;">
    Caption1<br>Caption1 Caption1 Caption1 Caption Caption Caption Caption Caption Caption
  </div>
  <div class="child" style="left:100%;">
    Caption2<br>Caption2 Caption2 Caption2 Caption2 Caption Caption Caption Caption Caption
  </div>
  <div class="child" style="background-color:magenta;left:100%;">
    Caption3<br>Caption3 Caption3 Caption3 Caption3 Caption Caption Caption Caption Caption
  </div>
  <div class="child" style="background-color:cyan;left:100%;">
    Caption4<br>Caption4 Caption4 Caption4 Caption4 Caption Caption Caption Caption Caption
  </div>
</div>
<br>
<span id="text"></span>

It works correctly if we press the “forward” and “back” buttons alternately (we can observe two slides), but it works incorrectly if we press one of these buttons several times (the previous slide disappears).

Does anyone know why it doesn’t work correctly or maybe there are any ideas how to improve the code?

Thank you in advance.

I tested in Firefox 74.0 (32bit). 'transform: translateX(...)' in css gives me the same behavior.

4
  • Please check this fiddle - jsfiddle.net/mightyteja/6a8gm7tu/10 Commented Apr 2, 2020 at 15:16
  • Dear mightyteja thank you for the answer. Unfortunately, the carousel in you jsfiddle does not work (no slide turning), at least for me in firefox. Commented Apr 2, 2020 at 15:23
  • I tested in firefox, I have added a click delay for the forward button(didn't add for backward), Also I added animation to control the carousel. Updated jsfiddle - jsfiddle.net/mightyteja/2eqnhmar/2 Commented Apr 2, 2020 at 15:29
  • In my navigator, the slides are changed without animation when the "forward" button is pressed Commented Apr 2, 2020 at 15:33

1 Answer 1

1

The slide with the prev_slideIndex already got the same value for the animation on the previous iteration of the carousel. Therefore you need to use reflow to force this slide to play the same animation one more time:

slides[prev_slideIndex].offsetHeight; /* trigger reflow */

var slideIndex = 0;
var prev_slideIndex = slideIndex;

function myanimate() {
  str = 'slideIndex=' + slideIndex + ' prev_slideIndex=' + prev_slideIndex;

  var slides = document.getElementsByClassName("child");
  for (var i = 0; i < slides.length; i++) slides[i].style.display = "none";

  if (prev_slideIndex < slideIndex) {
    if (slideIndex > 3) slideIndex = 0;
    slides[prev_slideIndex].style.left = '-100%';
    slides[prev_slideIndex].style.marginleft = '0%';
    slides[slideIndex].style.left = '0%';
    slides[slideIndex].style.marginleft = '0%';
    slides[prev_slideIndex].offsetHeight; /* trigger reflow */
    slides[prev_slideIndex].style.animation = slides[slideIndex].style.animation = 'caroussel 1.5s';
  } else {
    if (slideIndex < 0) slideIndex = 3;
    slides[prev_slideIndex].style.left = '100%';
    slides[prev_slideIndex].style.marginleft = '0%';
    slides[slideIndex].style.left = '0%';
    slides[slideIndex].style.marginleft = '0%';
    slides[prev_slideIndex].offsetHeight; /* trigger reflow */
    slides[prev_slideIndex].style.animation = slides[slideIndex].style.animation = 'caroussel_back 1.5s';
  }

  slides[prev_slideIndex].style.display = 'block';
  slides[slideIndex].style.display = 'block';
  prev_slideIndex = slideIndex;

  str += ' final prev_slideIndex=' + prev_slideIndex;
  document.getElementById("text").innerHTML = str;
}
.parent {
  background-color: red;
  display: block;
  position: relative;
  width: 600px;
  height: 100px;
  padding-top: 10px;
  padding-bottom: 10px;
  overflow: hidden;
}

.child {
  background-color: green;
  display: block;
  position: absolute;
  width: 100%;
  height: 100px;
  color: #FFFFFF;
  font-size: 24px;
  text-align: center;
}

@keyframes caroussel {
  from {
    margin-left: 100%
  }
  to {
    margin-left: 0%
  }
}

@keyframes caroussel_back {
  0% {
    margin-left: -100%
  }
  100% {
    margin-left: 0%
  }
}
<input type="submit" value='forward' title="sdg" onclick="slideIndex++;myanimate();">
<input type="submit" value='backward' title="sdg" onclick="slideIndex--;myanimate();">
<br>
<div class="parent">
  <div class="child" style="background-color:yellow;left:0%;">
    Caption1<br>Caption1 Caption1 Caption1 Caption Caption Caption Caption Caption Caption
  </div>
  <div class="child" style="left:100%;">
    Caption2<br>Caption2 Caption2 Caption2 Caption2 Caption Caption Caption Caption Caption
  </div>
  <div class="child" style="background-color:magenta;left:100%;">
    Caption3<br>Caption3 Caption3 Caption3 Caption3 Caption Caption Caption Caption Caption
  </div>
  <div class="child" style="background-color:cyan;left:100%;">
    Caption4<br>Caption4 Caption4 Caption4 Caption4 Caption Caption Caption Caption Caption
  </div>
</div>
<br>
<span id="text"></span>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.