Javascript is having problems with moving divs around
12:49 09 Jan 2018

Here's a function:

function rollImgOnSwipe(direction) {
    changeDirection(direction);
    rollImage(direction);
}

The first called function (changeDirection(direction);) is supposed to place a div in either the left or right side of the screen, depending on the value of its argument. The second one (rollImage(direction);) is to make the div move from left to right or from right to left, depending on where the first function placed it.

Well, it seems like it first calls rollImage and then changeDirection because it takes rollImgOnSwipe to be called more than once in order for the div to be placed on the other side.

The best way to explain this to you is to show you - run the code snippet and try switching between the divs with the prev and next buttons and see how they behave.

var nextBtn = document.getElementById('next'),
prevBtn = document.getElementById('prev'),
shown = document.getElementsByClassName('shown')[0],
hidden = document.getElementsByClassName('hidden')[0];

function rollImage(direction) {
shown.classList.remove("shown");
shown.classList.add("hidden");

hidden.classList.remove("hidden");
hidden.classList.add("shown");

shown = document.getElementsByClassName('shown')[0];
hidden = document.getElementsByClassName('hidden')[0];

changeDirection(direction);
}

function rollImgOnSwipe(direction) {
changeDirection(direction);
rollImage(direction);
}

function changeDirection(direction) {
hidden.style.left = (105 * direction) + "%";
shown.style.left = 0;
}

nextBtn.addEventListener('click', function () { rollImgOnSwipe(1); });
prevBtn.addEventListener('click', function () { rollImgOnSwipe(-1); });
.img {
position: absolute;
display: block;

width: 80px;
height: 30px;

border-style: solid;
border-color: red;
border-width: 5px;
}

.shown{
left: 0;
transition: left .6s ease, transform .6s ease;
}

.hidden{
left: 105%;
}

.img-wrapper{
position: relative;

width: 80px;
height: 30px;
padding: 30px;

white-space: nowrap;
overflow: hidden;
}


To fix this, i make the compiler wait for a bit before calling rollImage by using the setTimeout function in rollImgOnSwipe.

And now the program works as expected:

var nextBtn = document.getElementById('next'),
    prevBtn = document.getElementById('prev'),
    shown = document.getElementsByClassName('shown')[0],
    hidden =  document.getElementsByClassName('hidden')[0];

function rollImage(direction) {
    shown.classList.remove("shown");
    shown.classList.add("hidden");

    hidden.classList.remove("hidden");
    hidden.classList.add("shown");

    shown = document.getElementsByClassName('shown')[0];
    hidden = document.getElementsByClassName('hidden')[0];

    changeDirection(direction);
}

function rollImgOnSwipe(direction) {
    changeDirection(direction);
    setTimeout(function() { rollImage(direction); }, 50);
}

function changeDirection(direction) {
    hidden.style.left = (105 * direction) + "%";
    shown.style.left = 0;
}

nextBtn.addEventListener('click', function(){ rollImgOnSwipe(1); });
prevBtn.addEventListener('click', function(){ rollImgOnSwipe(-1); });
.img {
    position: absolute;
    display: block;

    width: 80px;
    height: 30px;

    border-style: solid;
    border-color: red;
    border-width: 5px;
}

.shown{
    left: 0;
    transition: left .6s ease, transform .6s ease;
}

.hidden{
    left: 105%;
}

.img-wrapper{
    position: relative;

    width: 80px;
    height: 30px;
    padding: 30px;

    white-space: nowrap;
    overflow: hidden;
}


My question is:

What is the problem and why is it fixed by making the compiler wait?

javascript html css