9

So I have been using ScrollIntoView() to jump to anchors in a react component as part of a web app. For small pages, it works fine, goes to the right spot and behaves as one would expect. I have one larger page where the behavior is strange. On loading, the jump to anchor is below where it should be by half a page or more. The first time one clicks on a link to any anchor, including the same anchor, the anchor ends up above where it should be by a similar amount. Every subsequent click after that works perfectly as long as the page is not reloaded. Here is my code for the function. It has a setTimeout because I thought that the problem had something to do with the page loading, but there is no effect. Here is my function:

scrollToAnchor: function () {
    let anchorName = this.props.location.hash || window.location.hash;
    if (anchorName) {
        anchorName = anchorName.replace("#", "");
        let anchorElement = document.getElementById(anchorName);
        if (anchorElement) {
            window.setTimeout(anchorElement.scrollIntoView(true), 0);
        }
    } else  {
        window.scrollTo(0, 0);
    }
},
suntruth
  • 101
  • 1
  • 4
  • Does this happen in all browsers? Have you checked the timeline for repaints? – enjoylife Mar 07 '16 at 21:58
  • I have tested in Chrome and Firefox and the problem exists in both. As for the timeline, the first paint on reload is where it first displays the anchor too high. On the first click, the anchor aligns to the right spot, but then repaints to a different spot. – suntruth Mar 08 '16 at 18:29
  • I'm having the same problem on the latest version of chrome on my Mac (not on windows), and an even stranger problem on Edge. Any workarounds? – Kevin LeStarge Oct 02 '17 at 21:48
  • Same exact issue. Any solutions? The answer below didn't help (`block:start, inline:nearest`). – gene b. Aug 01 '23 at 19:04

1 Answers1

0

In my case, I had to add the default params manually in order for it to work in some browsers. The block and inline params have an associated default value, but I had to put them in manually like this:

my_element.scrollIntoView(
   { behavior: 'smooth' , block: 'start', inline: 'nearest'}
);

Once I defined them in the scrollIntoViewOptions, it worked fine across all browsers.

PS: don't forget the polyfill for smooth scrolling.

Kevin LeStarge
  • 8,142
  • 4
  • 21
  • 34