0

So I am trying to implement a smooth scroll function using vanilla javascript. I found a solution here on stack overflow and made it work for my situation. I'm confused because the solution I have now passes a string to setTimeout. From what I've read it's preferable to pass a function instead. Unfortunately, I can't get it to work any other way.


The little part of the code that calls setTimeout looks like this:

setTimeout("window.scrollTo(0, " + leapY + ")", timer * speed);

I've tried it like this:

setTimeout(function() {window.scrollTo(0, leapY)}, timer * speed);

and instead of a smooth scroll it jumps to the top of the page.


Is there something I'm missing when it comes to passing anonymous functions to setTimeout?


The whole smooth scroll code block looks like this:

toTopButton.addEventListener('click', function () {
  var startY = window.pageYOffset;
  var stopY = 0;
  if (startY < 100) {
    scrollTo(0, stopY);
  }

  var speed = Math.round(startY / 100);
  if (speed >= 20) speed = 20;

  var step = Math.round(startY / 25);
  var leapY = startY - step;
  var timer = 0;
  for (var i = startY; i > stopY; i -= step) {
    setTimeout("window.scrollTo(0, " + leapY + ")", timer * speed);
    leapY -= step;
    if (leapY < stopY) {
      leapY = stopY
    };
    timer++;
  }
});

Quick explanation:

  • It's triggered when a 'toTop' button is clicked.
  • If yOffset < 100 it jumps to top. Otherwise speed is determined by distance from top and maxes out at 20.
  • A for loop negatively increments a variable equal to the start position by a predetermined leap value until start position equals 0.
  • Window is scrolled over time using setTimeout, the leap value, and an incremented timer.

Thank you for any insight you can offer!

Jeremon
  • 71
  • 1
  • 1
  • 5
  • Are you missing `}` when you call it via `anonymous function`? Or is it copy/paste mistake. Also see if you have any console errors in the browser.. – Guruprasad J Rao Feb 13 '18 at 03:58
  • theres no difference between passing an anonymous function vs passing a named function both will result in the same execution – Shanon Jackson Feb 13 '18 at 04:03
  • you should simplify your code to test instead of let us to understand your logic and test – xianshenglu Feb 13 '18 at 04:13
  • I see you are using straight javascript, but you can do this easily using jQuery and other libraries. An example can be found at https://stackoverflow.com/questions/15935318/smooth-scroll-to-top – SteveB Feb 13 '18 at 04:38
  • @GuruprasadRao thanks for pointing that out. That was a mistake when copying my code over. Definitely an error without that bracket but nothing when it's there. – Jeremon Feb 13 '18 at 04:50
  • The duplicate has more details, but in short: `setTimeout((function (leapY) { return function () { window.scrollTo(0, leapY); }; })(leapY), timer * speed);` should fix the problem. You might want to look into a different way, though, with a single timer running at a time (that starts another timer if the destination hasn’t been reached). – Ry- Feb 13 '18 at 04:51
  • @Ryan thank you. That way does work. But also raises a lot more questions for me. Many things that are still a mystery to me with javascript, but I appreciate the help! – Jeremon Feb 13 '18 at 04:59

0 Answers0