Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

$window.scrollTo() not handled correctly #89

Open
moosi opened this issue May 25, 2016 · 6 comments
Open

$window.scrollTo() not handled correctly #89

moosi opened this issue May 25, 2016 · 6 comments

Comments

@moosi
Copy link

moosi commented May 25, 2016

I discovered a problem using $window.scrollTo(). When using this function to trigger scroll events everything works fine as long as the scroller doesn't need to request new data from the data source. As soon as the scroller needs to request data from the data source the page will stop at a random position.

Here is a plnkr showing this problem: https://plnkr.co/edit/5jANsQnob1YE6DLrSgU6?p=preview

You can use the buttons on top to switch back and forth between position 0 and 100. Everything will work fine. But if you try to switch between position 0 and 2000 the scroller will stop once he needs to requests new data. After multiple times using the button you will reach position 2000 but the scroller won't correctly jump back to 0 (instead it will be something like 80).

@dhilt
Copy link
Member

dhilt commented May 25, 2016

This back-jump after the bottom line is reached and new rows are rendered is the behaviour by design. And the scroll position after that is not random, it reflects the state of the scroll bar before data fetch: the bottom visible row after all is the last row before new render.

And yes I see there is some delta while returning to the top and no matter how you do it ($window.scrollTo(0) or HOME button), I don't have a clear vision on this issue, but I think this may be caused by markup. Please look at the simple demo with fixed top border (-50 rows): http://rawgit.com/angular-ui/ui-scroll/master/demo/scrollBubblingPrevent/scrollBubblingPrevent.html -- HOME button works fine from any position, no delta.

@moosi
Copy link
Author

moosi commented Jun 13, 2016

Thank you dhilt, now I understand the scroll behaviour of my last plnkr. This time I created a example code that is really close to my actual challenge: https://plnkr.co/edit/BZhS8yI2VHqN16CiGLiN

Here I am using the combination of ui-router, ui-router-extras (to keep not visible states active) and ui-scroll. The 'Router' service is the core of the example. Each controller is registering it's scrollers and the service takes care about saving/restoring scroll positions and disabling/enabling scrollers.

I still have the problem that the position is not restored correctly but can't find a logic problem:

  1. Disable ALL scrollers
  2. Save scroll position
  3. Restore scroll position (or start at [0,0] if it's a new state)
  4. Enable scroller of current state (or do nothing if it's a new state)

Everything works as long as both tabs are within the same datasource range (e.g. index 5-10) but as soon as they are on different ranges (e.g. 5-10 and the other 10-15) the scroller starts reloading data and stops at the bottom visible row as you explained before. I don't understand why this data reload is happening since the scroller was getting disabled at state change start.

I added a lot of console output to show the sequence of what is happening.

@moosi
Copy link
Author

moosi commented Jul 6, 2016

Any updates regarding this?

@dhilt
Copy link
Member

dhilt commented Oct 13, 2016

@moosi sorry for late response! I'd like to try your demo on newest version of the ui-scroll component (v1.5.1), but there is an issue with v1.5.1 which would affect your demo too. So I'm going to fix that issue and then fix yours.

@dhilt
Copy link
Member

dhilt commented Oct 14, 2016

@moosi I followed your demo, the problem is that the scroll DOM is being completely destroyed during tab switching, so $window.scrollTo() could not work at all -- scroll bar params after rebuild do not match scroll bar params before destory.

But we have a mechanism of reload to specific item (official demo could be found here) wich could be useful in your case. Your plunker is too complicated, so I created another one (based on yours) to demonstrate how this feature could help. Please take a look: https://plnkr.co/edit/3nroueKn0BM28DgPZT6u?p=preview.

The main idea is to save top visible item scope before the tab is switched and then reload ui-scroll to a specific item (the scope of which we already have stored) after tab switching:

  $scope.$on('$stateChangeSuccess', function () {
    if(scrollPositionStorage[$state.current.name]) {
      ctrl.adapter.reload(scrollPositionStorage[$state.current.name].$index + 1);
    }
  });

  $scope.$on('$stateChangeStart', function () {
    scrollPositionStorage[$state.current.name] = ctrl.adapter.topVisibleScope;
  });

Note that in your demo you should not upgrade ui-scroll to 1.5.1 -- this would not work due to #119.

@moosi
Copy link
Author

moosi commented Oct 21, 2016

@dhilt thank you for taking your time! It seems like it is working the way you showed it in your plnkr but you need to use a $timeout. In my case the app is bigger and therefore the time it takes to switch between views is different each time. Since I use the browsers viewport my service also handles the enabling and disabling of the different scrollers. In this constellation it is getting even worse because sometimes it works as expected and sometimes the scroller is still disabled (or did not finished rendering) when receiving the reload(index) call. In this case the scroller is empty and won't show any data. Since the scroller does not provide any events like "finishedRendering" I see no possiblity to handle multiple scrollers reliable. Another strange thing is you said the DOM of the scroller is getting destroyed in my example, but:

  1. Scroll down in tab 1 for at least one data request
  2. Hit tab 2 and quickly return to tab 1
  3. You will see the DOM of tab1 with its big top margin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants