0

i have an angular website with multiple pages (sorry, can't link it here)

  1. Assume i'm in page A, and i've scrolled down somewhere (n pixels);
  2. There, i click a link to page B;
  3. Page B shows, but it's scrolled to the same hight as I was in page A (n pixels).

That's undesired: a linked page should start from its top (unless stated otherwise). I assume it stems from browser's built in functionality, e.g. a refresh operation will end up on the same scroll-position.

I tried to work around it by:

  1. remove all , thinking that angular's #/ navigation was trapped by an anchor. but it didn't matter.
  2. scrolling a newly opened view on ...

    • view-init
    • timeout (2-5 secs)
    • scope's "$on" event

but these caused page B to "jump" with noticeable delay; it bothers usability (and aesthetics).

i'm going to try to scroll to top on each link, just before going to, but it's difficult (and kind of silly)

suggestions?

edit

  • this is a Single Page app.
  • i have a "index.html", containing the tag.
  • pages are stored as html files (in the same directory)
Berry Tsakala
  • 15,313
  • 12
  • 57
  • 80

3 Answers3

1

you need to use $anchorScroll, have some field on top of the all the pages.. mostly in your layout.html with some id..

and then on $routeChangeRequest set your $location.hash to "#my-page-top-element"

var $locationChangeStart = function () { //evt, next, current
    var currentHash = $location.hash();
    if (angular.isUndefined(currentHash) || currentHash === null || currentHash === '') {
        $location.hash('ng-app');
    }
};

and this is what i have in my root controller...

$scope.$on("$locationChangeStart", routeManagerFactory.$locationChangeStart);
harishr
  • 17,807
  • 9
  • 78
  • 125
  • i'm not sure i'm following: what's "field on top" ? i don't have "layout.html" (i do have "index.html", containing ). Is it an addition or replacement to links and routes? – Berry Tsakala Jul 15 '14 at 19:12
  • how the $anchorScroll works it, it scrolls to and element with a given id, e.g. lets say id is 'ng-app', now if you have an element with id='ng-app' at top of the page the scroll will go to top, if its at bottom it goes to bottom... $location.hash('ng-app') will scoll the page to the id provided... – harishr Jul 15 '14 at 19:16
  • i'm not fluent enough in angular to fully understand your question, but i built a good-enough-solution based on your answer. dania baad – Berry Tsakala Jul 15 '14 at 20:04
  • i'll try your directive later today – Berry Tsakala Jul 16 '14 at 14:22
0

this is not the best solution, but it's enough in my case; It should be generalized to work on any page, not just A and B.

I've followed @HarishR 's answer, which seems better, had I learned it properly. Thank you, HarishR

BEFORE the route change, scroll to top (in page A's controller, the origin). This way the browser won't try to scroll down when arriving to page B.

Code in A's controller:

$scope.$on("$locationChangeStart", function(event) {
    var old = $location.hash();
    $location.hash('top');
    $anchorScroll();
    //reset to old to keep any additional routing logic from kicking in
    $location.hash(old);
};

And added id="top" on top of A.html

Berry Tsakala
  • 15,313
  • 12
  • 57
  • 80
0

i had written a directive to do that.. so that we don't have use to anchrorScroll...

csapp.directive('csScrollTop', ["$window", function ($window) {
    var linkFunction = function (scope) {
        scope.$on("$locationChangeSuccess", function () {
            $window.scrollTo(0, 0);
            //$("html, body").animate({ scrollTop: 0 }, "slow");
        });
    };

    return {
        restrict: 'E',
        link: linkFunction
    };
}]);

if you want to animate slow, uncomment the second line.. and comment out the first. and add this directive to you layout.html/index.html:

<cs-scroll-top></cs-scroll-top>

why i wanted this was because i dont want that #id to appear in the brower link box...

harishr
  • 17,807
  • 9
  • 78
  • 125