4

I have a div which contains a table for tabs in my site navigation. I have the div set to overflow when in mobile like this:

enter image description here

I want to have the div scroll to the, currently hidden, active tab automatically like this:

enter image description here

In another SA question it was suggested to use scrollIntoView. Tested it in the console and it works fine:

document.getElementById("active_tab").scrollIntoView({block: "end"})

I even used the jQuery version scrollintoview:

$('#active_tab').scrollintoview();

and it works fine. The trouble is that when I add the actual code (either one) to my site the overflow div on scrolls some random amount (seems to be half way). Here is an example:

enter image description here

Tried this in Chrome and Safari. Am I missing something obvious? I am not trying to scroll the whole page - just that div that has hidden overflow. Very odd that it work direct in the console but not in my code direct and for both JS and JQ. As far as I know there is no other JS etc related to this div etc.

Dan Tappin
  • 2,692
  • 3
  • 37
  • 77
  • Sometimes the problem is that it needs trusted event, as click or so. But didn’t thought this was in this list. How about debugging the actual code on site. – Akxe Jan 18 '20 at 23:55

1 Answers1

10

Hard to tell whats going on without seeing it live first-hand (can you link to the live site or make jsfiddle demo?) but i'll make a qualified guess;

It could be that when the scrolling happens programatically the menu isnt completely finished rendering. Maybe icons or the notifications arent showing yet, and so it scrolls to the right on a shorter menu and then widens as things get loaded.

You can test if this is the case by calling the code inside a setTimeout


Edit

A call to setTimeout(fn, 0) will run the fn immediately, but queued. Since this appears to have fixed your isse, it means some other task, that is already queued but has not quite run yet affects the width of the nav bar.

However, it's impossible to say exactly that is without seeing the code running first-hand. To find out yourself you can use the process of elimination:

For instance, try removing the setTimeout again, and remove the icons and see what happens. If you still have the issue, try adding the icons back and removing the notification numbers instead, etc.

xec
  • 17,349
  • 3
  • 46
  • 54
  • The timeout is a great idea. Will try that when I get home. The id is on the that is active. I would think the scroll would not even start if that element was not present. When you click on the visible elements there is no scroll at all which is expected. It’s also inside .ready which I until to wait until the DOM is fully loaded. – Dan Tappin Jan 19 '20 at 01:05
  • Completely bizarre - setTimeout works... even with the time set to zero lol. All alone I would accept this answer. I would like to know WHY this works and what's preventing the direct call to work. – Dan Tappin Jan 19 '20 at 23:37
  • Somehow worked for me as well.. Don't know why! `button.addEventListener('click', () => setTimeout(() => section.scrollIntoView(scrollConfig), 0));` – Adam Aug 24 '20 at 20:55
  • @DanTappin here's a great explanation of why setTimeout + 0 works, has to do with the event loop: https://stackoverflow.com/a/67657258/6837445 – saylestyler Aug 10 '22 at 15:23
  • As OP said, really depends on what's going on in your code where there's a possible race condition messing up layout during scrollIntoView call and requires setTimeout to fix. However I also encountered this strange issue where there is no race condition, just calling scrollIntoView in chrome devtools work but not when running from the script (made sure the function/evenListener is only calling scrollIntoView) – Caleb Taylor Aug 12 '22 at 13:49