Skip to content

Instantly share code, notes, and snippets.

@CMCDragonkai
Last active December 31, 2015 22:49
Show Gist options
  • Save CMCDragonkai/8055961 to your computer and use it in GitHub Desktop.
Save CMCDragonkai/8055961 to your computer and use it in GitHub Desktop.
JS: AngularJS Asynchronous Anchor Scroll - There are 3 ways of doing hash scrolling in AngularJS, put a hash into the URL via links, put a hash onto the URL via the $location API, or using $anchorScroll. All three ways rely on the URL having the hash component. The problem comes when the resource you want to scroll is loaded asynchronously, that…
app.directive('asyncAnchor', [
'$location',
'$anchorScroll',
'$timeout',
function($location, $anchorScroll, $timeout){
return {
link: function(scope, element, attributes){
var id = attributes.asyncAnchor || attributes.id || attributes.name;
var delay = attributes.asyncAnchorDelay;
var eventName = attributes.asyncAnchorEvent;
var firstTimeScrolling = true;
var scrollToHash = function(hash){
if(id && hash && id === hash){
if(delay && firstTimeScrolling){
$timeout(function(){
$anchorScroll();
}, delay);
}else{
$anchorScroll();
}
//only run the delay the first time this scrolling function executes
//if the hash didn't match, then this function didn't execute!
firstTimeScrolling = false;
}
};
//listen for a custom event, useful if you're waiting on something else to be fully loaded as well
if(eventName){
scope.$on(eventName, function(){
scrollToHash($location.hash());
});
}
//hash may be asynchronously changed, the directive may load before the hash is added
scope.$watch(function(){
return $location.hash();
}, function(hash){
scrollToHash(hash);
});
}
};
}
]);
@mlenser
Copy link

mlenser commented Oct 13, 2014

If anyone stumbles across this at a later point: AngularJS has this built in.

Add autoscroll="true" on your ng-view element and the page will scroll for you when the page loads (even with async content - I resolve that in the routing if it maters)

@litera
Copy link

litera commented Mar 26, 2015

@mlenser of course it matters. If you don't load your data using route resolve and load view model when controller i instatiated, then it's already too late for the $anchorScroll which will do that immediately when the view is being displayed (which is before you asynchronously load your data)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment