mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-18 23:50:23 +00:00
67 lines
2.2 KiB
JavaScript
67 lines
2.2 KiB
JavaScript
/**
|
|
* @ngdoc function
|
|
* @name ng.$anchorScroll
|
|
* @requires $window
|
|
* @requires $location
|
|
* @requires $rootScope
|
|
*
|
|
* @description
|
|
* When called, it checks current value of `$location.hash()` and scroll to related element,
|
|
* according to rules specified in
|
|
* {@link http://dev.w3.org/html5/spec/Overview.html#the-indicated-part-of-the-document Html5 spec}.
|
|
*
|
|
* It also watches the `$location.hash()` and scroll whenever it changes to match any anchor.
|
|
* This can be disabled by calling `$anchorScrollProvider.disableAutoScrolling()`.
|
|
*/
|
|
function $AnchorScrollProvider() {
|
|
|
|
var autoScrollingEnabled = true;
|
|
|
|
this.disableAutoScrolling = function() {
|
|
autoScrollingEnabled = false;
|
|
};
|
|
|
|
this.$get = ['$window', '$location', '$rootScope', function($window, $location, $rootScope) {
|
|
var document = $window.document;
|
|
|
|
// helper function to get first anchor from a NodeList
|
|
// can't use filter.filter, as it accepts only instances of Array
|
|
// and IE can't convert NodeList to an array using [].slice
|
|
// TODO(vojta): use filter if we change it to accept lists as well
|
|
function getFirstAnchor(list) {
|
|
var result = null;
|
|
forEach(list, function(element) {
|
|
if (!result && lowercase(element.nodeName) === 'a') result = element;
|
|
});
|
|
return result;
|
|
}
|
|
|
|
function scroll() {
|
|
var hash = $location.hash(), elm;
|
|
|
|
// empty hash, scroll to the top of the page
|
|
if (!hash) $window.scrollTo(0, 0);
|
|
|
|
// element with given id
|
|
else if ((elm = document.getElementById(hash))) elm.scrollIntoView();
|
|
|
|
// first anchor with given name :-D
|
|
else if ((elm = getFirstAnchor(document.getElementsByName(hash)))) elm.scrollIntoView();
|
|
|
|
// no element and hash == 'top', scroll to the top of the page
|
|
else if (hash === 'top') $window.scrollTo(0, 0);
|
|
}
|
|
|
|
// does not scroll when user clicks on anchor link that is currently on
|
|
// (no url change, no $location.hash() change), browser native does scroll
|
|
if (autoScrollingEnabled) {
|
|
$rootScope.$watch(function autoScrollWatch() {return $location.hash();},
|
|
function autoScrollWatchAction() {
|
|
$rootScope.$evalAsync(scroll);
|
|
});
|
|
}
|
|
|
|
return scroll;
|
|
}];
|
|
}
|
|
|