6

I am using Angular's scrollTo and anchorScroll like this:

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>

My problem is that when i click the link the page scrolls down, but in 50% of cases the page reloads because the hash changes in the URL.

How can I prevent Angular from reloading the page?

Update: I have found that here

https://groups.google.com/forum/?fromgroups=#!msg/angular/BY2ekZLbnIM/MORF-z2vHnIJ

that

The $location service broadcasts a $locationChangeStart event. You can observe that and call event.preventDefault() to stop the navigation. Nice!

can anyone tell how to observe that event and prevent default

user1865341
  • 4,099
  • 5
  • 18
  • 15

5 Answers5

9

The refresh is happening because there is a call to the locationChangeStart event. You can stop this by doing:

scope.$on('$locationChangeStart', function(ev) {
    ev.preventDefault();
});

I actually ended up writing my own scrollTo directive that uses this call inside of it.

Plnkr / Github

My other post about this here

Community
  • 1
  • 1
KhalilRavanna
  • 5,768
  • 3
  • 28
  • 24
6

You can add $event parameter onto ng-click handler:

<a ng-click="scrollTo('foo', $event)">Foo</a>

and in scrollTo function you can do the next:

scope.scrollTo = function(str, event) {
    event.preventDefault();
    event.stopPropagation();

    /** SOME OTHER LOGIC */
}

But that means that you should parse a target anchor hash from an "a" element manually.

oaleynik
  • 655
  • 5
  • 19
2

I think this may help u

$scope.redirectTodiv = function(divname,event) {
    var id = $location.hash();
    $location.hash(divname);
    $anchorScroll();
    $location.hash(id);
};

from: https://stackoverflow.com/a/25930875/4138368

Community
  • 1
  • 1
Choldrim
  • 41
  • 5
1

That event is emitted on the rootScope, so you can register an observer using the $on method.

$scope.$on('$locationChangeStart', function(ev) {
  ev.preventDefault();
});
cezar
  • 56
  • 3
  • I have put that in scrollTo function and it works but problem is then my other click on the left hand side menu stops working because that is chnaging the hash as well. how can i only prevent that when click on particualr links only – user1865341 Mar 19 '13 at 01:09
  • I'm not sure if you can. You'll probably have to manage those links with `$anchorScroll()` as well or rethink your design. By the way, that snippet goes into your controller function not in your `scrollTo` function. – cezar Mar 26 '13 at 18:28
0

To prevent the page from reloading in an angular anchor, add an empty href attribute.

<a href ng-click="scrollTo('foo')">Foo</a> OR <a href="" ng-click="scrollTo('foo')">Foo</a>

doc : https://docs.angularjs.org/api/ng/directive/ngHref

boismaxi
  • 9
  • 1