How to handle anchor hash linking in AngularJS
You're looking for $anchorScroll()
.
Here's the (crappy) documentation.
Basically you just inject it and call it in your controller, and it will scroll you to any element with the id found in $location.hash()
app.controller('TestCtrl', function($scope, $location, $anchorScroll) { $scope.scrollTo = function(id) { $location.hash(id); $anchorScroll(); }});<a ng-click="scrollTo('foo')">Foo</a><div id="foo">Here you are</div>
Here is a plunker to demonstrate
EDIT: to use this with routing
Set up your angular routing as usual, then just add the following code.
app.run(function($rootScope, $location, $anchorScroll, $routeParams) { //when the route is changed scroll to the proper element. $rootScope.$on('$routeChangeSuccess', function(newRoute, oldRoute) { $location.hash($routeParams.scrollTo); $anchorScroll(); });});
and your link would look like this:
<a href="#/test?scrollTo=foo">Test/Foo</a>
Here is a Plunker demonstrating scrolling with routing and $anchorScroll
And even simpler:
app.run(function($rootScope, $location, $anchorScroll) { //when the route is changed scroll to the proper element. $rootScope.$on('$routeChangeSuccess', function(newRoute, oldRoute) { if($location.hash()) $anchorScroll(); });});
and your link would look like this:
<a href="#/test#foo">Test/Foo</a>
In my case, I noticed that the routing logic was kicking in if I modified the $location.hash()
. The following trick worked..
$scope.scrollTo = function(id) { var old = $location.hash(); $location.hash(id); $anchorScroll(); //reset to old to keep any additional routing logic from kicking in $location.hash(old);};
There is no need to change any routing or anything else just need to use target="_self"
when creating the links
Example:
<a href="#faq-1" target="_self">Question 1</a><a href="#faq-2" target="_self">Question 2</a><a href="#faq-3" target="_self">Question 3</a>
And use the id
attribute in your html elements like this:
<h3 id="faq-1">Question 1</h3><h3 id="faq-2">Question 2</h3><h3 id="faq-3">Question 3</h3>
There is no need to use ## as pointed/mentioned in comments ;-)