Thanks Andy for the example, it was very helpful. I ended up implementing a slightly different strategy since I am developing one-page scrolling and do not want Angular to be updated when using the hashbang url. I also want to keep the browser back / forward action.
Instead of using directive and hash, I use $ scope. $ watch on $ location.search and get the target from there. This gives a nice clean anchor tag.
<a ng-href="#/?scroll=myElement">My element</a>
I chained the clock code to the declaration of my module in app.js as follows:
.run(function($location, $rootScope) { $rootScope.$watch(function() { return $location.search() }, function(search) { var scrollPos = 0; if (search.hasOwnProperty('scroll')) { var $target = $('#' + search.scroll); scrollPos = $target.offset().top; } $("body,html").animate({scrollTop: scrollPos}, "slow"); }); })
The caveat with the code above is that if you access the URL directly from another route, the DOM cannot be loaded in time to call jQuery $ target.offset (). The solution is to embed this code in the $ viewContentLoaded observer. The final code looks something like this:
.run(function($location, $rootScope) { $rootScope.$on('$viewContentLoaded', function() { $rootScope.$watch(function() { return $location.search() }, function(search) { var scrollPos = 0 if (search.hasOwnProperty('scroll')) { var $target = $('#' + search.scroll); var scrollPos = $target.offset().top; } $("body,html").animate({scrollTop: scrollPos}, "slow"); }); }); })
Tested with Chrome and FF
Marc Gibbons Sep 02 '13 at 19:27 2013-09-02 19:27
source share