Javascript AngularJS-$anchorScroll平滑/持续时间

Javascript AngularJS-$anchorScroll平滑/持续时间,javascript,angularjs,scroll,anchor-scroll,Javascript,Angularjs,Scroll,Anchor Scroll,阅读《我还没有弄清楚,$anchorScroll是否可以有一个持续时间/放松选项来平滑滚动到元素 它只说: $location.hash('bottom'); // call $anchorScroll() $anchorScroll(); 我不使用jquery,也不想使用;是否还有一种聪明而简单的方法来制作或扩展$anchorScroll,以使滚动更加平滑?不幸的是,使用$anchorScroll是不可能的。正如您发现的那样,$anchorScroll没有任何选项,并且不能与$ngAnim

阅读《我还没有弄清楚,
$anchorScroll
是否可以有一个持续时间/放松选项来平滑滚动到元素

它只说:

$location.hash('bottom');

// call $anchorScroll()
$anchorScroll();

我不使用jquery,也不想使用;是否还有一种聪明而简单的方法来制作或扩展
$anchorScroll
,以使滚动更加平滑?

不幸的是,使用
$anchorScroll
是不可能的。正如您发现的那样,
$anchorScroll
没有任何选项,并且不能与
$ngAnimate
一起使用。为了制作滚动动画,您需要使用自己的服务/工厂或直接javascript

为了自我学习,我制作了一个带有平滑滚动服务的示例。可能有更好的方法来做到这一点,因此鼓励任何反馈

要滚动到某个元素,请将
ng单击=“gotoElement(ID)”
附加到任何元素。我认为一个更好的办法是把它变成一个指令

这是我的建议

更新

现在有许多第三方指令可以实现这一点


    • 布雷特的回答对我很有用。我在模块化和可测试性方面对他的解决方案做了一些小改动

      下面是另一个包含测试的其他版本

      为了测试,我使用了Karma和Jasmine。签名稍作修改如下:

       anchorSmoothScroll.scrollTo(elementId, speed);
      

      其中元素是滚动到的强制属性,速度是可选的,默认值为20(与以前一样)。

      您也可以使用角度滚动链接“”。它还具有平滑滚动功能,以获得专业外观。

      您也可以使用ngSmoothScroll,链接:

      只需将
      smoothScroll
      模块作为依赖项包括在内,并按如下方式使用它:


      这里没有一个解决方案真正做到OP最初要求的,即使
      $anchorScroll
      平滑滚动。 平滑滚动指令和
      $anchoscorl
      之间的区别在于它使用/修改
      $location.hash()
      ,这在某些情况下可能是可取的

      下面是用平滑滚动代替$anchorScroll滚动的简单模块的要点。它使用库本身进行滚动(如果您愿意,可以用其他东西替换它,这应该很容易)


      注意:它实际上没有使$anchorScroll平滑滚动,但它替换了用于滚动的处理程序


      只需在应用程序中引用
      mdvoraksoothscroll
      模块即可启用它。

      Alan,谢谢。如果有人感兴趣,我根据John Pappa标准格式化了它

      (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);
                      }
                  }
      
              }
      
          };
      
      };
      
      })();
      
      (函数(){
      "严格使用",;
      var moduleId=‘公共’;
      var serviceId='anchorsmoothsroll';
      有棱角的
      .模块(模块ID)
      .服务(服务ID、主持人名单);
      anchorSmoothScroll.$inject=['$document','$window'];
      函数主播平滑滚动($document,$window){
      var document=$document[0];
      var窗口=$window;
      var服务={
      向下滚动:向下滚动,
      向上滚动:向上滚动,
      滚动到:滚动到,
      scrollToTop:scrollToTop
      };
      回程服务;
      函数getCurrentPagePosition(currentWindow,doc){
      //Firefox、Chrome、Opera、Safari
      如果(currentWindow.pageYOffset)返回currentWindow.pageYOffset;
      //Internet Explorer 6-标准模式
      if(doc.documentElement&&doc.documentElement.scrollTop)
      返回doc.documentElement.scrollTop;
      //Internet Explorer 6、7和8
      如果(doc.body.scrollTop)返回doc.body.scrollTop;
      返回0;
      }
      函数getElementY(文档,元素){
      变量y=元素偏移量;
      var节点=元素;
      while(node.offsetParent&&node.offsetParent!==doc.body){
      node=node.offsetParent;
      y+=node.offsetTop;
      }
      返回y;
      }
      功能向下滚动(起始、停止、速度、距离){
      var定时器=0;
      var步长=数学圆(距离/25);
      var leapY=起点+步长;
      对于(var i=开始;i<停止;i+=步骤){
      setTimeout('window.scrollTo(0,+leapY+'),计时器*速度);
      跳跃+=步进;
      如果(leapY>stopY)leapY=stopY;
      定时器++;
      }
      };
      功能向上滚动(起始、停止、速度、距离){
      var定时器=0;
      var步长=数学圆(距离/25);
      var leapY=起始步长;
      对于(变量i=开始;i>停止;i-=步骤){
      setTimeout('window.scrollTo(0,+leapY+'),计时器*速度);
      跳跃-=步进;
      如果(leapY开始?停止-开始:开始-停止;
      如果(距离<100){
      这个。滚动totop(stopY);
      }否则{
      var defaultSpeed=数学圆(距离/100);
      速度=速度| |(默认速度>20?20:默认速度);
      如果(停止>开始){
      这个。向下滚动(起点、终点、速度、距离);
      }否则{
      向上滚动(起点、终点、速度、距离);
      }
      }
      }
      };
      };
      })();
      
      我不知道如何设置
      $anchorScroll
      的动画。以下是我在项目中的做法:

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

      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;
      }
      

      我们可以使用JQuery和Javascript以及指令在锚定标记单击时执行滚动到特定div的操作

      请检查下面链接上的工作示例-

      Ver