diff options
| author | Misko Hevery | 2012-03-23 14:03:24 -0700 | 
|---|---|---|
| committer | Misko Hevery | 2012-03-28 11:16:35 -0700 | 
| commit | 2430f52bb97fa9d682e5f028c977c5bf94c5ec38 (patch) | |
| tree | e7529b741d70199f36d52090b430510bad07f233 /src/ng/anchorScroll.js | |
| parent | 944098a4e0f753f06b40c73ca3e79991cec6c2e2 (diff) | |
| download | angular.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.js | 66 | 
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; +  }]; +} + | 
