How to do smooth scrolling on browser back/next button on same-page navigation?

526 views
Skip to first unread message

Ed

unread,
May 5, 2015, 7:51:25 AM5/5/15
to google-we...@googlegroups.com
I have a sticky top menu with menu items that perform smooth scrolling (through GreenSock) to a certain page location (I stay on the same page all the time).
It will also add a History token for every unique page location.
That works fine, it scrolls smooth and the back/next browser buttons work "well".

However, no smooth scrolling occurs when the back/next browser buttons are used as the browser will jump to the previous location immediately, before even History.onHasChanged() is called (detected through a breakpoint) :(

In my History handler I calculate the required scrolling distance, which is zero because the browser already jumped (scrolled) to the previous page location.
How can I perform the smooth scrolling when the browser  back/next buttons are used?

Is there any way, to disable this browser behavior? (cancel the browser back/next event), or replace the browser back/next behavior?


Gilberto

unread,
May 9, 2015, 8:46:42 AM5/9/15
to google-we...@googlegroups.com
I wouldn't recommend disabling the back/next behavior. For your case, you could save the scroll position of each View (using a ScrollHandler to catch the events), and when the History is changed, scroll to the current View position (or to the top if the View is a new one) using Window.moveTo, or another method from your library.

Something like this:

private Map<String, Point> scrollPositions = new HashMap<>();

Window.addWindowScrollHandler(new Window.ScrollHandler(){
   
@Override
   
public void onWindowScroll(Window.ScrollEvent event){
        scrollPositions
.put(History.getToken(), new Point(event.getScrollLeft(), event.getScrollTop()));
   
}
});

History.addValueChangeHandler(new ValueChangeHandler<String>(){
   
@Override
   
public void onValueChange(ValueChangeEvent<String> event){
       
Point p = scrollPositions.get(event.getValue());
       
if (p == null) p = new Point(0,0);
       
Window.moveTo(p.getX(), p.getY()); //or something else from your lib
   
}
});


For a library to handle History tokens and page navigation that a look at this post. ;-)

Ed Bras

unread,
May 10, 2015, 5:47:24 AM5/10/15
to google-we...@googlegroups.com
@Gilbert, thanks, but don't think I made myself clear, sorry for that. 
What you are writing is exactly what I do, the problem is that before I can perform the scrolling myself because I capture a History event the browser did already the scrolling for me like explained in my original post.

btw: I don't need to store scolling positions as the scrolling sections contain unique id's that are used for scrolling, but also as navigation from other places in the app.

Jens

unread,
May 10, 2015, 9:37:13 AM5/10/15
to google-we...@googlegroups.com
So if its so important to you to smooth scroll then you have to implement it yourself without using the native browser behavior. E.g. use any tag with data-scroll-id=section-1 attribute and search that element whenever you get a history change event for #section-1

Since your site should not have an element with id=section-1 or an anchor with name=section-1 the browser won't jump to anything on its own. You would also need to trigger scrolling when the page gets (re)loaded as the browser won't do it anymore.

-- J.

Ed Bras

unread,
May 10, 2015, 6:49:11 PM5/10/15
to google-we...@googlegroups.com
@Jens, thanks I think this is the problem:
Since your site should not have an element with id=section-1 
Interesting... wasn't aware of that, that is what I do and will probably be the problem .  I will change it, using the data- attribute as you suggest and let you know how it works.

I tried to search for the info about when/how the browser does add a History token, but can't find it. If you have a link, please share.

The Smooth scrolling is already done through (the same) History markers through click events/navigation (menu), so it's nice if it also happens in case of back/forward. It looks weird if it only works half...




Message has been deleted

jaga

unread,
May 11, 2015, 4:03:06 PM5/11/15
to google-we...@googlegroups.com
Is it possible for you to use LayoutPanels? If you can then you get animation for free. You can easily do smooth scrolling using this.

Ed Bras

unread,
May 11, 2015, 4:08:14 PM5/11/15
to google-we...@googlegroups.com
@Jaga: I already have the smooth scrolling for free through the components I use.
The problem is probably that I use the "id" attribute like @Jens mention, which I will also do in LayoutPanel ;).. 
I am about to test it, I will come back on it.

Ed Bras

unread,
May 12, 2015, 4:51:32 AM5/12/15
to google-we...@googlegroups.com
@Jens: I don't think your solution isn't working.

You mentioned I should not use id attribute, and instead use something like data-scroll-id.
I change it now to for example: <div data-id="blaMarker">...</div>, but still the browser jumps on pressing the history back button before I can process my history marker. 

Details: 
As soon as a person arrives as a certain part of the page I set a history marker (as hash) in the url, like example: 
"#NvWrkDcUsgSt?id=IdUsgSelect"​
The first part indicates the page to be shown and the id parts the section on the page. 
The target Element containing the id part: <div data-id="idUsgSelect">...</div>

So when the History change event is fired with the above history value, I stop in the GWT class History.onHashChanged() through a breakpoint, but then the browser already jumped to the position when the history marker was added to the url.

Apparently the browser will record the scroll position of the page when the url is changed and jumps back to it when it appears in the browser history during back/forward actions.
But is there anyway to ensure the browser will scroll smoothly instead of jumping ...?



Jens

unread,
May 12, 2015, 5:18:46 AM5/12/15
to google-we...@googlegroups.com
Well then your only option is probably pushState. If the browser does not support pushState then you are out of luck.

-- J.

Ed Bras

unread,
May 12, 2015, 5:35:53 AM5/12/15
to google-we...@googlegroups.com
​@Jens: thanks, i hoped I missed something simple.
I think I just leave it for now. It's more a "nice-2-have" and there are more important thinks now,a and I remember messing with the browser history can become a bit hairy..
Reply all
Reply to author
Forward
0 new messages