Andrew Delaney
Andrew Delaney

Reputation: 31

Why Is My Function Alternating Between Working and Then Not Javascript

This is my very first ever question asked here, so I do apologise in advance if I am not following correct guidelines.

Basically what I'm trying to do is to manually code side-section navigating in Javascript. The navigating itself is working just fine, one can click either left or right and the sections will scroll left and right endlessly in a carousel. But when I try to set the previous pages scrollTop back to 0 once the user has moved off the section I run into problems.

If I scroll through each section and scroll a bit of the way down on each, when I return to the first page and cycle through them again, they seem to alternate as to whether their scrollTop was actually set to 0.

HTML body:

<div class="Arrow" id="arrowLeft"></div>
<div class="Arrow" id="arrowRight"></div>
<section class="Page" id="page1"><div class="PageContent"></div></section>
<section class="Page" id="page2"><div class="PageContent"></div></section>
<section class="Page" id="page3"><div class="PageContent"></div></section>
<section class="Page" id="page4"><div class="PageContent"></div></section>
<section class="Page" id="page5"><div class="PageContent"></div></section>
<section class="Page" id="page6"><div class="PageContent"></div></section>
<section class="Page" id="page7"><div class="PageContent"></div></section>
<section class="Page" id="page8"><div class="PageContent"></div></section>
<script src="JavaScript/scroller.js"></script>

Javascript:

//initialising variables and populating arrays
var currentPage = 0;
var previousPage = 0;
var pages = document.getElementsByClassName("Page");
var sections = [];
for (i=0;i<pages.length;i++) {
    sections.push(pages[i]);
}
var pageOffSets = [0, 100, 200, 300, 400, -300, -200, -100];
var zOffSets = [0,-1,-2,-3,-4,-3,-2,-1];
for (i = 0;i<sections.length;i++) {
    sections[i].style.left = pageOffSets[i] + "vw";
    sections[i].style.zIndex = zOffSets[i];
}


//Navigate function
function slidePage(direction) {
        previousPage = currentPage;
    if (direction=="right") {
        currentPage+=1;
        if (currentPage>7) {
            currentPage = 0;
        }
        var hold = sections.shift();
        sections.push(hold);

         for (i=0;i<sections.length;i++) {
            sections[i].style.left = pageOffSets[i] + "vw";
            sections[i].style.zIndex = zOffSets[i];
        }
    }

    if (direction=="left") {
        currentPage-=1;
        if (currentPage<0) {
            currentPage = 7;
        }
        var hold = sections.pop();
        sections.unshift(hold);

         for (i=0;i<sections.length;i++) {
            sections[i].style.left = pageOffSets[i] + "vw";
            sections[i].style.zIndex = zOffSets[i];
        }
    }

    //!!!
    //This is the part that is supposed to set the scrollTop back to 0
    //!!!
    setTimeout(function(){
        sections[previousPage].scrollTop = 0;
    }, 1000);
}


//Event listeners for when the user clicks
document.getElementById("arrowLeft").addEventListener("click", function(){
    slidePage("left");
});
document.getElementById("arrowRight").addEventListener("click", function(){
    slidePage("right");
});

I would really appreciate if someone could point out what I'm doing wrong.

Edit: Here is the CSS if you need it:

body {
  overflow-x: hidden;
  overflow-y: scroll;
}

section {
  width: 100vw;
  height: 100vh;
  position: fixed;
  -webkit-transition-duration: 0.4s;
          transition-duration: 0.4s;
  overflow: scroll;
}

.Arrow {
  position: absolute;
  z-index: 1;
  width: 50px;
  height: 50px;
  background-color: black;
  top: 48%;
}

.Arrow:hover {
  cursor: pointer;
}

#arrowRight {
  right: 0;
}

#page1 {
  background-color: #c81996;
}

#page2 {
  background-color: #64324b;
}

#page3 {
  background-color: #1996c8;
}

#page4 {
  background-color: #324b64;
}

#page5 {
  background-color: #96c819;
}

#page6 {
  background-color: #4b6432;
}

#page7 {
  background-color: #f0fa1e;
}

#page8 {
  background-color: #fa1ef0;
}

.PageContent {
  height: 8000px;
  width: 90vw;
  margin: 5vw;
  background-image: -webkit-gradient(linear, left top, left bottom, from(red), to(yellow));
  background-image: linear-gradient(red, yellow);
  position: absolute;
}

Upvotes: 0

Views: 73

Answers (1)

vgru
vgru

Reputation: 51224

There are two problems:

  1. You are rotating the sections array inside your function, so the previousPage index is no longer correct once your anonymous function is fired.

  2. The previousPage variable referenced when setting scrollTop after the timeout can change before the timeout elapses.

The simplest fix would be to rotate pageOffSets and zOffSets arrays instead:

if (direction == "right") {

    currentPage++;

    if (currentPage >= sections.length) {
        currentPage = 0;
    }

    // rotate pageOffsets    
    {
        var x = pageOffSets.pop();
        pageOffSets.unshift(x);
    }

    // rotate zOffsets
    {
        var x = zOffSets.pop();
        zOffSets.unshift(x);
    }

     for (i=0;i<sections.length;i++) {
        sections[i].style.left = pageOffSets[i] + "vw";
        sections[i].style.zIndex = zOffSets[i];
    }

} else {

    currentPage--;

    if (currentPage < 0) {
        currentPage = sections.length - 1;
    }

    // rotate pageOffsets    
    {
        var x = pageOffSets.shift();
        pageOffSets.push(x);
    }

    // rotate zOffSets    
    {
        var x = zOffSets.shift();
        zOffSets.push(x);
    }  

     for (i=0;i<sections.length;i++) {
        sections[i].style.left = pageOffSets[i] + "vw";
        sections[i].style.zIndex = zOffSets[i];
    }
}

And you need to capture a copy of the previousPage variable:

// capture a copy of the index so that it doesn't change
var prev = previousPage;

setTimeout(function() {
    sections[prev].scrollTop = 0;
}, 500);

Upvotes: 1

Related Questions