scroll position is not restored when using defaultPageTransition = "none" #7148

Closed
jamiepk opened this Issue Feb 21, 2014 · 11 comments

Comments

Projects
None yet
2 participants
@jamiepk

jamiepk commented Feb 21, 2014

Hi guys -

Hopefully I can make this understandable.


ISSUE DESCRIPTION
I currently use $.mobile.defaultPageTransition = "none" on my site.

When clicking a link on my search results page, then clicking a data-rel="back" link from the details page, the scroll position on the search results is not correctly restored, and seems to always return to the position of the first item clicked.


TEST PAGE
http://jsbin.com/IFolanOW/281/edit


STEPS TO REPRODUCE ISSUE

  1. Scroll to item 2
  2. Click item 2
  3. Click 'back'
  4. Scroll position is at item 2
  5. Scroll to item 3
  6. Click item 3
  7. Click 'back'
  8. Scroll position is not item 3, but item 2

STEPS TO REPRODUCE CORRECT BEHAVIOR

  1. Comment out defaultPageTransition from mobileinit
  2. Do steps above

EXPECTED OUTCOME
Position of last item clicked on search results when clicking 'back' would be restored to clicked position (normal browser behavior)


ACTUAL OUTCOME
Seems like the first item clicked is cached, and you will always return to that item.


PLATFORMS
Chrome desktop (most recent)
Safari iOS7

@gabrielschulhof

This comment has been minimized.

Show comment
Hide comment
@gabrielschulhof

gabrielschulhof Feb 21, 2014

Contributor

A simplified test:

  1. git version: http://jsbin.com/IFolanOW/282
  2. 1.3.2 version: http://jsbin.com/IFolanOW/283

It's only broken on Chrome (so, presumably on Blink/Webkit)

Contributor

gabrielschulhof commented Feb 21, 2014

A simplified test:

  1. git version: http://jsbin.com/IFolanOW/282
  2. 1.3.2 version: http://jsbin.com/IFolanOW/283

It's only broken on Chrome (so, presumably on Blink/Webkit)

@gabrielschulhof

This comment has been minimized.

Show comment
Hide comment
@gabrielschulhof

gabrielschulhof Feb 21, 2014

Contributor

Steps:

  1. Page down to the first occurrence of the link.
  2. Click the link.
  3. Click the browser's "Back" button.
  4. Page down to the second occurrence of the link.
  5. Click the browser's "Back" button.
Contributor

gabrielschulhof commented Feb 21, 2014

Steps:

  1. Page down to the first occurrence of the link.
  2. Click the link.
  3. Click the browser's "Back" button.
  4. Page down to the second occurrence of the link.
  5. Click the browser's "Back" button.
@gabrielschulhof

This comment has been minimized.

Show comment
Hide comment
@gabrielschulhof

gabrielschulhof Feb 21, 2014

Contributor

Starting a table:

Browser1.3.2git
FF27
Chrome 32/Linux 
WP7.5  
Android 2.3.5
iOS 6.1 
WP8 
Contributor

gabrielschulhof commented Feb 21, 2014

Starting a table:

Browser1.3.2git
FF27
Chrome 32/Linux 
WP7.5  
Android 2.3.5
iOS 6.1 
WP8 
@gabrielschulhof

This comment has been minimized.

Show comment
Hide comment
@gabrielschulhof

gabrielschulhof Feb 21, 2014

Contributor

I've isolated the problem a bit on Chrome 32/Linux: It turns out that the pagecontainer stops receiving scrollstop events after you come back from Page 2.

Contributor

gabrielschulhof commented Feb 21, 2014

I've isolated the problem a bit on Chrome 32/Linux: It turns out that the pagecontainer stops receiving scrollstop events after you come back from Page 2.

@gabrielschulhof

This comment has been minimized.

Show comment
Hide comment
@gabrielschulhof

gabrielschulhof Feb 21, 2014

Contributor

Actually, it's broken on FF too ... you just have to go to Page 2 one more time.

Contributor

gabrielschulhof commented Feb 21, 2014

Actually, it's broken on FF too ... you just have to go to Page 2 one more time.

@gabrielschulhof

This comment has been minimized.

Show comment
Hide comment
@gabrielschulhof

gabrielschulhof Feb 21, 2014

Contributor

Tracing further on Chrome ... when you come back from Page 2, the page container's _disableRecordScroll method gets called so it stops recording scrollTop.

Contributor

gabrielschulhof commented Feb 21, 2014

Tracing further on Chrome ... when you come back from Page 2, the page container's _disableRecordScroll method gets called so it stops recording scrollTop.

@gabrielschulhof

This comment has been minimized.

Show comment
Hide comment
@gabrielschulhof

gabrielschulhof Feb 21, 2014

Contributor

The reason it stops working is that the pagecontainer does not receive a navigate event when returning from Page 2. It has a handler for navigate which would turn scroll recording back on. On FF it receives the navigate event upon the first return, but not the second, and on Chrome it doesn't receive the navigate event even after the first return.

Contributor

gabrielschulhof commented Feb 21, 2014

The reason it stops working is that the pagecontainer does not receive a navigate event when returning from Page 2. It has a handler for navigate which would turn scroll recording back on. On FF it receives the navigate event upon the first return, but not the second, and on Chrome it doesn't receive the navigate event even after the first return.

@gabrielschulhof

This comment has been minimized.

Show comment
Hide comment
@gabrielschulhof

gabrielschulhof Feb 22, 2014

Contributor

Basically, pagecontainer has a flag setLastScrollEnabled which causes the scrollstop event handler to save the scrollTop whenever the flag is set to true. On later returns to the first page, this flag is no longer being set to true.

Contributor

gabrielschulhof commented Feb 22, 2014

Basically, pagecontainer has a flag setLastScrollEnabled which causes the scrollstop event handler to save the scrollTop whenever the flag is set to true. On later returns to the first page, this flag is no longer being set to true.

@gabrielschulhof

This comment has been minimized.

Show comment
Hide comment
@gabrielschulhof

gabrielschulhof Feb 22, 2014

Contributor

Why does pagecontainer have a navigate event handler which turns off setLastScrollEnabled?
Why does the navigate event (which turns off the flag) occur after the pagechange event (which turns the flag back on)?

Contributor

gabrielschulhof commented Feb 22, 2014

Why does pagecontainer have a navigate event handler which turns off setLastScrollEnabled?
Why does the navigate event (which turns off the flag) occur after the pagechange event (which turns the flag back on)?

@gabrielschulhof

This comment has been minimized.

Show comment
Hide comment
@gabrielschulhof

gabrielschulhof Feb 22, 2014

Contributor

OK. I believe I have identified the root cause. During _create, the pagecontainer attaches two handlers to the "navigate" event: One that disables scrollTop tracking, and one that performs the page change. It attaches the scrolling disabler last. This is bad because, when there's no transition, the pagechange happens synchronously, so the pagechange handler, which turns the scrollTop tracking back on, is run before the navigate handler, which turns the scrollTop tracking off. So, the net result is that the scrollTop tracking is off.

The solution is simple: Attach the handler that performs the page change after the handler that turns off the scrolling.

Contributor

gabrielschulhof commented Feb 22, 2014

OK. I believe I have identified the root cause. During _create, the pagecontainer attaches two handlers to the "navigate" event: One that disables scrollTop tracking, and one that performs the page change. It attaches the scrolling disabler last. This is bad because, when there's no transition, the pagechange happens synchronously, so the pagechange handler, which turns the scrollTop tracking back on, is run before the navigate handler, which turns the scrollTop tracking off. So, the net result is that the scrollTop tracking is off.

The solution is simple: Attach the handler that performs the page change after the handler that turns off the scrolling.

@jamiepk

This comment has been minimized.

Show comment
Hide comment
@jamiepk

jamiepk Feb 22, 2014

Thanks for this Gabriel. I've tested and works perfect. Thanks for the hard work!

jamiepk commented Feb 22, 2014

Thanks for this Gabriel. I've tested and works perfect. Thanks for the hard work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment