orlando21
orlando21

Reputation: 307

How does AngularJS routing affect simple "scroll to top" page links?

I'm using a HTML anchor tag for a "back to top" link in the footer of my web page:

<a href="#top" class="footer__top">Back to top</a>

At the top of the page I inserted another anchor tag in the HEAD tag:

<a id="#top"></a>

I've also implemented AngularJS by declaring my app on the HTML tag of index.html:

<html lang="en" ng-app="myApp">

... and I'm using routing as follows:

angular.module('myApp', [
  'ui.router'
])
.config(['$stateProvider', '$locationProvider', function($stateProvider, $locationProvider) {
  $stateProvider
   .state('home', {
      url: '/'
  });
    $locationProvider
        .html5Mode({
        enabled: true,
        requireBase: false
    });
}]);

I intend in the future to make the page a full-fledged AngularJS app, but for now all this is a minimal declaration (so controllers, etc., are not included yet).

However, when I add a minimal AngularJS declaration as such, I observe strange behavior when clicking on the "back to top" link in the footer. The first time I click on this link, the page scrolls to the top as intended.

But the second time I click on it, nothing occurs. To sum up, the link doesn't work when clicking on it twice in a row.

Might anyone have an explanation for this behavior? When I remove the Angular code, the link behaves as it should.

Upvotes: 0

Views: 114

Answers (1)

Shantanu
Shantanu

Reputation: 3513

Yes if you're using conventional anchor tag with href hash linking, then it'll conflict with routing. In angular there's service called $anchorScroll to do that, so your html should be:

<a ng-click="goTo('top')" class="footer__top">Back to top</a>

And in controller of that view have function goTo as:

$scope.goTo = function(id) {
    $location.hash(id);
    $anchorScroll();
};

Make sure you've injected $location & $anchorScroll as dependencies inside controller.

Plunker

Now above solution is for having hash linking on same page/route. But i you need such in other route then you can handle that centrally on event of $routeChangeSuccess or $stateChangeSuccess or in recent ui-router version Transition.onSuccess as:

$rootScope.$on('$routeChangeSuccess', function(newRoute, oldRoute) {
    $location.hash($routeParams.scrollTo);
    $anchorScroll();  
  });

And in some other view have anchor tags like:

<a href="#route1?scrollTo=foo">route1 / Foo</a>
<a href="#route2?scrollTo=bar">route2 / Bar</a>

Plunker

Upvotes: 1

Related Questions