AngularJS – $ anchorScroll平滑/持续时间

阅读AngularJS文档我还没有弄清楚,如果$anchorScroll可以有一个持续时间/宽松的选项来平滑滚动到元素。

它只是说:

 $location.hash('bottom'); // call $anchorScroll() $anchorScroll(); 

我不使用jquery,也不想; 是否仍然有一个聪明而简单的方法来制作或扩展$anchorScroll以使滚动更加stream畅?

不幸的是,这是不可能使用$anchorScroll 。 当您发现$anchorScroll没有任何选项,并且不能使用$ngAnimate 。 为了animation滚动,你将需要使用自己的服务/工厂或只是直的JavaScript。

为了自学,我以一个平滑的滚动服务为例。 有可能有更好的方法来做到这一点,所以鼓励任何反馈。

要滚动到一个元素,您可以将ng-click="gotoElement(ID)"附加到任何元素。 我认为一条更好的路线就是将这个指令作为一个指令。

这里是jsFiddle的工作示例 。

更新

现在有一些第三方指令来完成这个。

您也可以使用angular度滚动,链接“ https://github.com/durated/angular-scroll/ ”。 这是顺利滚动也很less有缓和function,以获得专业的外观。

Brett的回答对我很好。 我在模块化和可testing性方面做了一些小的改动。

这里是JsFiddle的另一个工作示例,其中包括其他版本的testing。

为了testing,我使用Karma和Jasmine。 签名已经稍微修改如下:

  anchorSmoothScroll.scrollTo(elementId, speed); 

其中元素是滚动到的必需属性,速度是默认值为20(如以前那样)的可选属性。

你也可以使用ngSmoothScroll,链接: https : //github.com/d-oliveros/ngSmoothScroll 。

只要将smoothScroll模块作为一个依赖项来使用就像这样:

<a href="#" scroll-to="my-element-3">Click me!</a>

这里没有一个解决scheme实际上是OP最初要求的,也就是让$anchorScroll平滑滚动。 平滑滚动指令和$anchroScroll之间的$anchroScroll在于它使用/修改了$location.hash() ,在某些情况下这可能是可取的。

这是简单模块的要点,用平滑滚动replace$ anchorScroll滚动。 它使用https://github.com/oblador/angular-scroll库来滚动本身(如果你愿意的话,用其他东西代替它,应该很容易)。;

https://gist.github.com/mdvorak/fc8b531d3e082f3fdaa9
注意:它实际上没有获得$ anchorScroll的顺利滚动,但它取代了它的滚动处理程序。

通过在您的应用程序中引用mdvorakSmoothScroll模块来启用它。

艾伦,谢谢。 如果有人感兴趣,我根据约翰帕帕标准格式化。

 (function() { 'use strict'; var moduleId = 'common'; var serviceId = 'anchorSmoothScroll'; angular .module(moduleId) .service(serviceId, anchorSmoothScroll); anchorSmoothScroll.$inject = ['$document', '$window']; function anchorSmoothScroll($document, $window) { var document = $document[0]; var window = $window; var service = { scrollDown: scrollDown, scrollUp: scrollUp, scrollTo: scrollTo, scrollToTop: scrollToTop }; return service; function getCurrentPagePosition(currentWindow, doc) { // Firefox, Chrome, Opera, Safari if (currentWindow.pageYOffset) return currentWindow.pageYOffset; // Internet Explorer 6 - standards mode if (doc.documentElement && doc.documentElement.scrollTop) return doc.documentElement.scrollTop; // Internet Explorer 6, 7 and 8 if (doc.body.scrollTop) return doc.body.scrollTop; return 0; } function getElementY(doc, element) { var y = element.offsetTop; var node = element; while (node.offsetParent && node.offsetParent !== doc.body) { node = node.offsetParent; y += node.offsetTop; } return y; } function scrollDown(startY, stopY, speed, distance) { var timer = 0; var step = Math.round(distance / 25); var leapY = startY + step; for (var i = startY; i < stopY; i += step) { setTimeout('window.scrollTo(0, ' + leapY + ')', timer * speed); leapY += step; if (leapY > stopY) leapY = stopY; timer++; } }; function scrollUp(startY, stopY, speed, distance) { var timer = 0; var step = Math.round(distance / 25); var leapY = startY - step; for (var i = startY; i > stopY; i -= step) { setTimeout('window.scrollTo(0, ' + leapY + ')', timer * speed); leapY -= step; if (leapY < stopY) leapY = stopY; timer++; } }; function scrollToTop(stopY) { scrollTo(0, stopY); }; function scrollTo(elementId, speed) { var element = document.getElementById(elementId); if (element) { var startY = getCurrentPagePosition(window, document); var stopY = getElementY(document, element); var distance = stopY > startY ? stopY - startY : startY - stopY; if (distance < 100) { this.scrollToTop(stopY); } else { var defaultSpeed = Math.round(distance / 100); speed = speed || (defaultSpeed > 20 ? 20 : defaultSpeed); if (stopY > startY) { this.scrollDown(startY, stopY, speed, distance); } else { this.scrollUp(startY, stopY, speed, distance); } } } }; }; })(); 

我不知道如何animation$anchorScroll 。 以下是我在项目中的做法:

 /* Scroll to top on each ui-router state change */ $rootScope.$on('$stateChangeStart', function() { scrollToTop(); }); 

而JSfunction:

 function scrollToTop() { if (typeof jQuery == 'undefined') { return window.scrollTo(0,0); } else { var body = $('html, body'); body.animate({scrollTop:0}, '600', 'swing'); } log("scrollToTop"); return true; }