Skip to content

Increment array up to max items

I’ve written this code. It rotates two divs like a card flip using css transform every 1000ms and displays new text in the div, which is drawn from an array. It runs infinitely.

But once the array reaches its end I get an ‘undefined’ value because the i++ is incrementing on the final array item. I have been going crazy trying to figure out how to prevent that. Any help?

Codepen: https://codepen.io/warpigs666/pen/OJpBKdy

    <style>
        #flip-card {
            width: 100px;
            height: 50px;
        }
        #flip-card-inner {
            position: relative;
            width: 100%;
            height: 100%;
            transition: transform 0.6s;
            transform-style: preserve-3d;
        }
        #textDiv1 {
            background-color: lightblue;
            position: absolute;
            width: 100%;
            height: 100%;
            backface-visibility: hidden;
            text-align: center;
        }
        
        #textDiv2 {
            background-color: lightcoral;
            position: absolute;
            width: 100%;
            height: 100%;
            backface-visibility: hidden;
            text-align: center;
            transform: rotateX(180deg);
        }
    </style>

<body>
    
    <div id="flip-card">
        <div id="flip-card-inner">
            <div id="textDiv1">
                one
            </div>
            <div id="textDiv2">
                set via script
            </div>
        </div>
    </div>
   
    <script>
        var flipCard = document.getElementById('flip-card');
        var flipCardInner = document.getElementById('flip-card-inner');
        var textDiv1 = document.getElementById('textDiv1');
        var textDiv2 = document.getElementById('textDiv2');
        var wordArray = ["one", "two", "three", "four", "five"]

        var i = 1;

        function flipText(){   
            textDiv2.innerHTML = wordArray[i];
            flipCardInner.style.transform = "rotateX(180deg)";
            
            setTimeout(
                function() {
                    textDiv1.innerHTML = wordArray[i++];
                    flipCardInner.style.transform = "rotateX(360deg)";
                }, 1000
            );
            
            if (i<wordArray.length){
                i++;
            }
                else {i=0;}
        }
        
            var flipIt = setInterval(flipText, 2000);
        
    </script>
</body>

Answer

This is a job for setInterval

var flipCard = document.getElementById('flip-card');
let flipCardInner = document.getElementById('flip-card-inner');
let textDiv1 = document.getElementById('textDiv1');
let textDiv2 = document.getElementById('textDiv2');
let wordArray = ["one", "two", "three", "four", "five"];

let i = 0;
let timerVal = 1000;

function getI(i) {
  if (i < wordArray.length - 1) return i + 1;
  else return 0;
}
let ctr = 1,
  useDiv; // ctr and useDiv will help to toggle between divs in our loop and also increment the transform number

textDiv1.innerHTML = wordArray[i]; // initialize 

function flipText() {
  i = getI(i);
  useDiv = (useDiv == textDiv2) ? textDiv1 : textDiv2;
  useDiv.innerHTML = wordArray[i];
  flipCardInner.style.transform = "rotateX(" + (ctr * 180) + "deg)";
  ctr++;
}

let interval
window.onload = function() {
  // we'll still delay the beginning of the infinite loop, but then we set it to an interval, so it runs forever.
  // if you need to stop it in your code, just use clearInterval(interval)
  setTimeout(() => {
    interval = setInterval(() => flipText(), timerVal);
  }, timerVal);
}
#flip-card {
  width: 100px;
  height: 50px;
  perspective: 100px;
}

#flip-card-inner {
  position: relative;
  width: 100%;
  height: 100%;
  transition: transform 0.6s;
  transform-style: preserve-3d;
}

#textDiv1 {
  background-color: lightblue;
  position: absolute;
  width: 100%;
  height: 100%;
  backface-visibility: hidden;
  text-align: center;
}

#textDiv2 {
  background-color: lightcoral;
  position: absolute;
  width: 100%;
  height: 100%;
  backface-visibility: hidden;
  text-align: center;
  transform: rotateX(180deg);
}
<div id="flip-card">
  <div id="flip-card-inner">
    <div id="textDiv1">

    </div>
    <div id="textDiv2">

    </div>
  </div>
</div>