Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scroll page to hash position on page reload - AngularJS

I am developing a website with angularJS and using twitter bootstrap for UI. I have some hash Ids associated with certain section, so that when user click on navigation, page scrolls down to that section. And its working fine for me.

Here the site link: https://powerful-cliffs-1105.herokuapp.com/about

Now in about page. I have right navigation which scrolls page to specific position. But when i reload that page, page starts from top and doesn't scroll down to hash position, like https://powerful-cliffs-1105.herokuapp.com/about#management

There are two solutions for the above problem:

  1. Either remove hash tag from URL when we reload that page.
  2. Scroll page to particular(hash) section on page reload.

Since i am still learning angularJS, i am unable to find any concrete solution of above problem.

Any help is greatly appreciated.

like image 375
Mohit Pandey Avatar asked Dec 22 '14 09:12

Mohit Pandey


1 Answers

Use the $anchorScroll service.

The problem here, is that Angular loads the about content dinamically, so when you have the hash you don't have the content ready. $anchorScroll tracks the hash and scroll it for you.

// Just borrow from your code    
angular.module('aboutController', []).controller('aboutController',['$scope', '$location', '$anchorScroll', 
    function($scope, $location, $anchorScroll) {

  $scope.isActive = function(route){
     return route === $location.hash();
  }

  $anchorScroll();
}]);

Edit 31/12:

Since Mohit (the creator of the question) said that my solution didn't work for him, I decided to download the code and work locally. My solution worked locally, which made me scrach my head, but I'd like to point a few editions in the code that probably (or most probably not) can solve the issue.

Move the scripts to the bottom of the page (index.html)

<!-- ANGULAR DYNAMIC CONTENT -->
  <div class="body" ng-view></div>

  <!-- FOOTER -->
  <footer ng-include="'views/footer.html'"></footer>

  <!-- JS -->
  <script src="js/libs/angular/angular.min.js"></script>
  <script src="js/libs/angular-bootstrap/ui-bootstrap.min.js"></script>
  <script src="js/libs/angular-bootstrap/ui-bootstrap-tpls.min.js"></script>
  <script src="js/libs/angular-route/angular-route.min.js"></script>

  <!-- ANGULAR CUSTOM CONTROLLERS -->
  <script src="js/controllers/home.js"></script>
  <script src="js/controllers/about.js"></script>
  <script src="js/controllers/contact.js"></script>

  <!-- ANGULAR CUSTOM FACTORIES -->
  <script src="js/services/contact.js"></script>

  <!-- UTILITY FILE -->
  <script src="js/utils/util.js"></script>

  <!-- ANGULAR CUSTOM ROUTES AND APP -->
  <script src="js/route-provider.js"></script>
  <script src="js/app.js"></script>
</body>

Remove/comment, for now, the html5Mode (route-provider.js)

// $locationProvider.html5Mode(true);

and append /#/ before accessing the URLs, like this

Put a timeout

This is by far the one I don't suggest, but certainly you can give a shot

$timeout(function() {
    $anchorScroll(); 
}, 0)
like image 135
Rigotti Avatar answered Sep 30 '22 15:09

Rigotti