Skip to content

State change scrolls page to top #110

Closed
@rynz

Description

@rynz

If you create a scrollbar, eg by resizing the Sampe App. Whenever you change state, it scrolls to the top of the page.

If state changes, it shouldn't look like a browser refresh, rather change the nested elements accordingly and maintain where the scrollbar is set.

Eg:
Run Sample App.
Click Contacts.
Resize Sample App so you have a scrollbar.
Scroll to bottom
Click "Show random contact" or Email or Edit etc

The page will jump to the top.

Is this the desired effect?

Activity

legomind

legomind commented on May 1, 2013

@legomind

According to angularjs docs, the $anchorScroll service scrolls to the top of the page when $location.hash() is empty or when it contains a reference to an element that does not exist.

This behavior can be disabled in with the following code in the config section of your angular app.

$anchorScrollProvider.disableAutoScrolling()

So, yes. This is the desired behavior.

rynz

rynz commented on May 1, 2013

@rynz
Author

@legomind Unfortunately calling $state.transitionTo with url parameter in it's corresponding $state it still jumps to the top of the page even with $anchorScrollProvider.disableAutoScrolling().

ksperling

ksperling commented on May 2, 2013

@ksperling
Contributor

ui-view has inherited the call to $anchorScroll from core-Anglar ng-view. The idea seems to be that the content added by the view's template might make a previously invalid anchor valid, thus the call to $anchorScroll.

It's all not ideal though... But I think this might need looking at properly outside of the context of just ui-router.

rynz

rynz commented on May 2, 2013

@rynz
Author

@ksperling I guess I can understand from the point of ng-view because generally that's an entire view change instead of this much nicer state change solution.

I noticed in the Sample App changing between contacts.detail.item and contacts.detail.item.edit state, even though it does not update the anchor it still scrolls to top. Perhaps a configurable option for ui-view to allow / disallow whether scroll to top is enabled on state change. Perhaps a rule based system similar to $urlRouterProvider passing true/false on whether scroll to top happens?

jeme

jeme commented on May 2, 2013

@jeme
Contributor

As @ksperling says, the scrolling feature of angular core is properly better to change, if you don't wan't it you could provide your own implementation. Like so:

var $AnchorScrollProvider = function() {
  this.$get = ['$window', '$location', '$rootScope', function($window, $location, $rootScope) {
    function scroll() {
    }
    return scroll;
  }];
}
angular.module('yourApp').provider('$anchorScroll', $AnchorScrollProvider);

that should disable scroll all together (remember to depend on the module you put the alternated provider in if not your app module)...

Even in the fine grained views, scrolling to top is the appropriate default action, think of a case where the newly loaded content was activated from the bottom of the page, but takes up more than a window can hold, would you wan't the view to show the bottom initially?... The user properly wan't to read your newly loaded content from the top.

There can be cases though where you don't wan't that, and I think that is where the current $anchorScroll is to simple, I am especially annoyed about it solely using the hash value, if I wanted /blog/post/42/comments to load the page and scroll to the comments section, I can't using $anchorScroll instead I have to use: /blog/post/42#comments

The ui-router project could overwrite it's behavior I guess. That would be one option to explore making it more. Or we could simply not use it in ui-view, but i still think we should scroll to top as the default behavior, and why not use/extend the component that is meant to do that.

rynz

rynz commented on May 2, 2013

@rynz
Author

@ksperling @jeme I do agree it is very situational and the default behavior is desirable in most cases. I also think if ui-router implemented a $urlAnchorScrollProvider or something of this nature to apply rules and returning false to disable scroll many people would take advantage of it.

Or something hopefully Angular-Core could think about.

A prime example is if we use state to generate a lightbox, something we want people to be able to link to. It will scroll to top and lose your current position of the background content.

ksperling

ksperling commented on May 5, 2013

@ksperling
Contributor

If we can do something better in ui-router that would be good. Maybe coming up with what the desired behaviour would be in a number of different cases would be a good start, e.g. quite often a state will update multiple views to if they all try to scroll an arbitrary one is going to "win"... Maybe the scroll behaviour should be specified for each state as a whole?

rynz

rynz commented on May 6, 2013

@rynz
Author

@ksperling Personally I think the default behavior should be do not scroll, then have an option when configuring each state of scrollToState: true or something of that nature. So whenever we transitionTo a particular state it will decide whether to scroll or not.

The only most common case to scrollToState would be navigation states imo, where as states like a lightbox, toggling etc should not effect scroll state.

laurelnaiad

laurelnaiad commented on May 6, 2013

@laurelnaiad

+1 for default being not to scroll. I'm pretty new to Angular -- are there mechanisms that an app could use to scroll when it wants to? I hope so!

jeme

jeme commented on May 6, 2013

@jeme
Contributor

@SparkiO @stu-salsbury scolling to top (not to state, what does that even entail if the state has multiple views???) would be the most desired case I think, after all I think most pages will consist of more "content" loading that dialogs.

Take this example of a page and a view-port location:

Simple page

Wouldn't you wan't the page to scroll up so you can instantly begin to read from the beginning of the article or what the main content may be?... And even if you are loading an outer view, same rule would apply, we always read from the top.

Then I think we should be able to do things like:

  • scrollTo:top - scroll to top, explicitly stated. (This also enables one to override another scrollTo from a parent)
  • scrollTo:null - don't scroll, not even to top.
  • scrollTo:@viewname - scroll to a view.
  • scrollTo:elementid - scroll to an element id
  • scrollTo:['$stateParams', function($stateParams) { return stateParams.section; } - scroll to element with id or view if starts with @

Then the default for a state would be: (pseudo code)

state.scrollTo = state.scrollTo || (state.parent && state.parent.scrollTo) || 'top'...

laurelnaiad

laurelnaiad commented on May 6, 2013

@laurelnaiad

I like your thinking about the options, @jeme. I guess the scrolling might
relate to whether one is in the mindset of web app or web site (or
where we all probably live which is somewhere on the spectrum in between).
I like the inheritance idea (assuming the default stretches not just to
the parent state (or view) but all the way up to the root) because the
developer can make a decision at the root that essentially becomes the
site/app default.

jeme

jeme commented on May 6, 2013

@jeme
Contributor

@stu-salsbury it would, since that if the parent state isn't a root, it would have done the same trick to calculate it's scroll value, the "scroll" var was meant to be set on the internal wrapper object for states. That might not have been clear from the example. I have updated the comment to try and make that more clear.

However, since there is no "global root" in ui-router, it would have to be an option for the $stateProvider to maybe set some defaults... like: $stateProvider.defaults({ ... }); or another way.

rynz

rynz commented on May 6, 2013

@rynz
Author

@jeme I like it. I also like the idea of setting the default behavior depending on which you need more. Scroll to top, or scroll to null.

28 remaining items

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Development

      Participants

      @nateabele@wkonkel@juanpujol@bernardolm@arush

      Issue actions

        State change scrolls page to top · Issue #110 · angular-ui/ui-router