1

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;
}
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
I Want Answers
  • 371
  • 3
  • 15
  • You code will add a new interval event on every scroll. This is a bad practice. – Rajesh Dec 24 '15 at 07:19
  • @Rajesh the function called has a loop that checks IF it should be called in the first place. If the condition is not satisfied, it is not called at all. – I Want Answers Dec 24 '15 at 07:29
  • try something like this: [JSfiddle](https://jsfiddle.net/RajeshDixit/cgyjsL3m/) – Rajesh Dec 24 '15 at 07:35
  • @Rajesh it seems as though the clearInterval function in your fiddle does not work because on each scroll, the interval function fires over and over. Secondly, the reason for the `for` loop in my code is to check mate the string array popping of more characters than necessary. Your code keeps popping and `shift`ing even after the `firstString` chars has been exhausted – I Want Answers Dec 24 '15 at 15:36

2 Answers2

1

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.

Community
  • 1
  • 1
jbmartinez
  • 624
  • 5
  • 8
  • thanks. although yours didn't work immediately, the problem was the variable ```scrollTop``` was in the global scope and was set to default on 0 so the condition was not actually met. Another thing is, the scrollTop property on chrome accepts both strings and numbers alike though you might argue using numbers is safer. Lastly, the function is called just 3 times because I set an instance of the ```setInterval``` function in the event listener so it does run a million times. Here is a fiddle that works at my end https://jsfiddle.net/nmeri17/1Lw0vn1w/ – I Want Answers Dec 25 '15 at 12:30
  • Also you can use `var distanceSoFar = document.body.scrollTop || document.documentElement.scrollTop;` to checkmate browsers that don't accept the former. – I Want Answers Dec 25 '15 at 12:40
0

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> 
Tom Sebastian
  • 3,373
  • 5
  • 29
  • 54