Anchor links in Angularjs?

Angularjs

Angularjs Problem Overview


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

Angularjs Solutions


Solution 1 - Angularjs

There are a few ways to do this it seems.

Option 1: Native Angular

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.

Option 2: Custom Directive / Native JavaScript

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?

Option 3: Angular Override / Native Browser

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.

Solution 2 - Angularjs

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: https://stackoverflow.com/questions/14712223/how-to-handle-anchor-hash-linking-in-angularjs

Solution 3 - Angularjs

You could try to use anchorScroll.

Example

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>

Solution 4 - Angularjs

$anchorScroll is indeed the answer to this, but there's a much better way to use it in more recent versions of Angular.

Now, $anchorScroll accepts the hash as an optional argument, so you don't have to change $location.hash at all. (documentation)

This is the best solution because it doesn't affect the route at all. I couldn't get any of the other solutions to work because I'm using ngRoute and the route would reload as soon as I set $location.hash(id), before $anchorScroll could do its magic.

Here is how to use it... first, in the directive or controller:

$scope.scrollTo = function (id) {
  $anchorScroll(id);  
}

and then in the view:

<a href="" ng-click="scrollTo(id)">Text</a>

Also, if you need to account for a fixed navbar (or other UI), you can set the offset for $anchorScroll like this (in the main module's run function):

  .run(function ($anchorScroll) {
      //this will make anchorScroll scroll to the div minus 50px
      $anchorScroll.yOffset = 50;
  });

Solution 5 - Angularjs

I had the same problem, but this worked for me:

<a ng-href="javascript:void(0);#tagId"></a>

Solution 6 - Angularjs

Works for me:

 <a onclick='return false;' href="" class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" ng-href="#profile#collapse{{$index}}"> blalba </a>

Solution 7 - Angularjs

You need to only add target="_self" to your link

ex. <a href="#services" target="_self">Services</a><div id="services"></div>

Solution 8 - Angularjs

Or you could simply write:

ng-href="\#yourAnchorId"

Please notice the backslash in front of the hash symbol

Solution 9 - Angularjs

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();
      });      
    }
  };
});

Solution 10 - Angularjs

If you are using SharePoint and angular then do it like below:

<a ng-href="{{item.LinkTo.Url}}" target="_blank" ng-bind="item.Title;" ></a> 

where LinkTo and Title is SharePoint Column.

Solution 11 - Angularjs

You can also Navigate to HTML id from inside controller

$location.hash('id_in_html');

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAndriy DrozdyukView Question on Stackoverflow
Solution 1 - AngularjsCourcelanView Answer on Stackoverflow
Solution 2 - AngularjsPaola CerioliView Answer on Stackoverflow
Solution 3 - AngularjsEdmar MiyakeView Answer on Stackoverflow
Solution 4 - AngularjsRebeccaView Answer on Stackoverflow
Solution 5 - AngularjsLeonardo Silva do NascimentoView Answer on Stackoverflow
Solution 6 - AngularjsImran Omar BukhshView Answer on Stackoverflow
Solution 7 - AngularjsFarzad.KamaliView Answer on Stackoverflow
Solution 8 - AngularjsMarkoView Answer on Stackoverflow
Solution 9 - AngularjsMárcio MarinhoView Answer on Stackoverflow
Solution 10 - AngularjsAmay KulkarniView Answer on Stackoverflow
Solution 11 - AngularjsvijayView Answer on Stackoverflow