Weird scrolling issue


#1

This is going to be a somewhat vague question, but I’m hoping to get some insight or hints at where to look for the underlying cause of my problem.

Basically, I’m wondering what would cause a DIV with its own scroll bar/position to reset to the top upon clicking a {{link-to}} within the DIV that simply updates the query params of the current route. I have to be vague, because my app is quite complicated, so I’m not sure if I can adequately narrow it down to a base JSfiddle or Ember Twiddle But I will try to describe it:

I have one main DIV that I’ve set to the the remaining height allotted to it, via something like height: calc(100vh - 100px);. This DIV uses flex to create three panels side-by-side, each with their own scrollbar ( overflow-y: scroll;).

The panel I’m having problems with has basically one contextual component that renders a bunch of other components. It also has {{link-to}}s that simply update the query parameters of the same route. If I click on any of these links, this panel’s scroll position gets reset to the top. And I can’t figure out why. Even if I create a dummy URL param that doesn’t actually affect any of the components, the scroll position resets.

The weird thing is, if I shrink the browser window enough, so the DIV occupies maybe 150-200px of screen space instead of its usual ~500px when the browser is full screen, then the scroll position won’t reset. The threshold seems to be around 400px.

At this point, I have no idea where to even start debugging this problem. I don’t expect anyone to give me an answer to my specific problem, but what I would like are some possible clues or things I should look at to debug this issue. Could it be a rendering issue (like maybe the DIV is blank for a frame or two, so the scrollbar is reset, before the components are re-rendered?

BTW, I’m on Ember 2.7.x


#2

I haven’t been able to figure out why the scrolling resets, but I have a workaround. I basically have a function bound to the scroll event, where I keep track of the current scroll location. I then check if the current value is 0, and the previous value is greater than some threshold (I found 100 works well). If so, then I reset the position to the old value.

handleScroll(e) {
  let targetDiv = get(this, 'targetDiv');     // CSS selector of panel with scrollbar
  let prevScrollPosition = get(this, 'scrollPosition');
  let currScrollPosition = this.$(targetDiv).scrollTop();
  if (currScrollPosition === 0 && prevScrollPosition > 100) {
    this.$(targetDiv).scrollTop(prevScrollPosition);
    return;
  }
  set(this, 'scrollPosition', currScrollPosition);
},

This approach feels all sorts of hacky and not ideal, but it works for my use case. I still hope to figure out the underlying issue though.