I Want Answers
I Want Answers

Reputation: 441

Nested setInterval function on scroll not working

I am trying to set interval to a function that is only called when user scrolls below a certain height. My code return no errors and the function does not run either. However, I tried logging a random number at the end of the function and it doesn't so I think it has to do with my function. Take a look:

var firstString = ["This ", "is ", " me."];
var firstPara = document.querySelector("#firstPara");
var distanceSoFar = (document.body.scrollTop);

window.addEventListener("scroll", function() {
  setInterval(slideIn, 450);
});

function slideIn() {
  if (distanceSoFar > "130") {
    for (var i = 0; i < firstString.length; i++) {
      var stringOut = firstString.shift();
      firstPara.innerHTML += stringOut;
      console.log("5");
    }
  }
};

firstPara is just a paragraph in a div on the page. So the idea is to place some text in it on interval when a user scrolls into that view like so:

body {
height: 1000px;
}

div {
position: relative;
top: 700px;
}

div #firstPara {
border: 1px solid;
}

Upvotes: 1

Views: 1000

Answers (2)

jbmartinez
jbmartinez

Reputation: 634

Part of your code is working. It handles the scroll event correctly and the slideIn function is called but the condition distanceSoFar > "130" is never met.

I'd suggest two changes to make your code work as you expect:

  1. Use document.documentElement.scrollTop instead of document.body.scrollTop. document.body.scrollTop may return incorrect values (0) on some browsers. Look at this answer, for example.
  2. Declare distanceSofar inside of the slideIn function. You declared the variable on the top of your code, so it stores a static value of the scrollTop property.

I'd avoid using setInterval inside a scroll event handler, you are setting a lot of intervals and not clearing them. I added some console.logs to show you how the slideIn function keeps being called even when the user is not scrolling.

A final tip: the scrollTop property is a number, so you can compare it to 130 instead of "130".

Here is the working fiddle.

Upvotes: 1

Tom Sebastian
Tom Sebastian

Reputation: 3433

I tried your code. I think it is working as you expected. I also added a clearInterval inorder to clear the timer after printing all text and also to avoid repeated calling.

<html>
   <head>
   <style>
        body {
        height: 1000px;
        }

        div {
        position: relative;
        top: 700px;
        }

        div #firstPara {
        border: 1px solid;
        }
   </style>
   <script>
       function start(){
          var s =0;
          var interval =  undefined;
           function slideIn() {
           console.log(distanceSoFar);
              if (distanceSoFar > "130") {
                while ( firstString.length > 0) {
                  var stringOut = firstString.shift();
                  firstPara.innerHTML += stringOut;
                  console.log(s++);
                }
                clearInterval(interval);
                interval = undefined;
              }
            };

            var firstString = ["This ", "is ", " me."];
            var firstPara = document.querySelector("#firstPara");
            var distanceSoFar = (document.body.scrollTop);

            window.addEventListener("scroll", function() {
            if(!interval)
              interval = setInterval(slideIn, 450);
            });
       };



   </script>
   </head>
   <body onload="start()">
    <div id="firstPara"/>
   </body>
  <html> 

Upvotes: 0

Related Questions