aboutsummaryrefslogtreecommitdiffstats
path: root/src/ng/anchorScroll.js
diff options
context:
space:
mode:
authorMisko Hevery2012-03-23 14:03:24 -0700
committerMisko Hevery2012-03-28 11:16:35 -0700
commit2430f52bb97fa9d682e5f028c977c5bf94c5ec38 (patch)
treee7529b741d70199f36d52090b430510bad07f233 /src/ng/anchorScroll.js
parent944098a4e0f753f06b40c73ca3e79991cec6c2e2 (diff)
downloadangular.js-2430f52bb97fa9d682e5f028c977c5bf94c5ec38.tar.bz2
chore(module): move files around in preparation for more modules
Diffstat (limited to 'src/ng/anchorScroll.js')
-rw-r--r--src/ng/anchorScroll.js66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/ng/anchorScroll.js b/src/ng/anchorScroll.js
new file mode 100644
index 00000000..19a09498
--- /dev/null
+++ b/src/ng/anchorScroll.js
@@ -0,0 +1,66 @@
+/**
+ * @ngdoc function
+ * @name angular.module.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 $locaiton.hash() change), browser native does scroll
+ if (autoScrollingEnabled) {
+ $rootScope.$watch(function() {return $location.hash();}, function() {
+ $rootScope.$evalAsync(scroll);
+ });
+ }
+
+ return scroll;
+ }];
+}
+