Is it possible to use anchor links with Angularjs?
I.e.:
<a href="#top">Top</a>
<a href="#middle">Middle</a>
<a href="#bottom">Bottom</a>
<div name="top"></div>
...
<div name="middle"></div>
...
<div name="bottom"></div>
Thank you
There are a few ways to do this it seems.
Angular provides an $anchorScroll
service, but the documentation is severely lacking and I've not been able to get it to work.
Check out http://www.benlesh.com/2013/02/angular-js-scrolling-to-element-by-id.html for some insight into $anchorScroll
.
Another way I tested out was creating a custom directive and using el.scrollIntoView()
.
This works pretty decently by basically doing the following in your directive link function:
var el = document.getElementById(attrs.href);
el.scrollIntoView();
However, it seems a bit overblown to do both of these when the browser natively supports this, right?
If you take a look at http://docs.angularjs.org/guide/dev_guide.services.$location and its HTML Link Rewriting section, you'll see that links are not rewritten in the following:
Links that contain target element
Example:
<a href="/ext/link?a=b" target="_self">link</a>
So, all you have to do is add the target
attribute to your links, like so:
<a href="#anchorLinkID" target="_self">Go to inpage section</a>
Angular defaults to the browser and since its an anchor link and not a different base url, the browser scrolls to the correct location, as desired.
I went with option 3 because its best to rely on native browser functionality here, and saves us time and effort.
Gotta note that after a successful scroll and hash change, Angular does follow up and rewrite the hash to its custom style. However, the browser has already completed its business and you are good to go.
I don't know if that answers your question, but yes, you can use angularjs links, such as:
<a ng-href="http://www.gravatar.com/avatar/{{hash}}"/>
There is a good example on the AngularJS website:
http://docs.angularjs.org/api/ng.directive:ngHref
UPDATE: The AngularJS documentation was a bit obscure and it didn't provide a good solution for it. Sorry!
You can find a better solution here: How to handle anchor hash linking in AngularJS
You could try to use anchorScroll.
So the controller would be:
app.controller('MainCtrl', function($scope, $location, $anchorScroll, $routeParams) {
$scope.scrollTo = function(id) {
$location.hash(id);
$anchorScroll();
}
});
And the view:
<a href="" ng-click="scrollTo('foo')">Scroll to #foo</a>
...and no secret for the anchor id:
<div id="foo">
This is #foo
</div>
Or you could simply write:
ng-href="\#yourAnchorId"
Please notice the backslash in front of the hash symbol
The best choice to me was to create a directive to do the work, because $location.hash() and $anchorScroll() hijack the URL creating lots of problems to my SPA routing.
MyModule.directive('myAnchor', function() {
return {
restrict: 'A',
require: '?ngModel',
link: function(scope, elem, attrs, ngModel) {
return elem.bind('click', function() {
//other stuff ...
var el;
el = document.getElementById(attrs['myAnchor']);
return el.scrollIntoView();
});
}
};
});