【问题标题】:AngularJS Scroll to element prevent browser from jumpingAngularJS滚动到元素防止浏览器跳转
【发布时间】:2013-12-03 01:19:57
【问题描述】:

我编写了一个包含块列表的应用程序。

每个块都包含指向其他块的链接。 当点击一个块的链接时,例如#/home/page-19,页面会根据当前位置向下/向上动画。

这一切目前都有效,但是当点击锚点并且路线更新时,浏览器会跳到顶部然后向下动画,我需要它从当前位置开始动画。

我编写了一个指令,将 preventDefault 添加到所有锚点。

参见下面的 JS fiddle。 http://jsfiddle.net/ygNWF/10/

精简代码:

HTML:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>

<body ng-app="app" ng-controller="appController">
    <script type="text/ng-template" id="home-template">
       <div class="page" id="page-17" >
              <div class="page-inner" ng-style="style()" resize><a href="#/home/page-18">Page 18</a></div>
          </div>
          <div class="page" id="page-18">
              <div class="page-inner" ng-style="style()" resize><a href="#/home/page-19">Page 19</a></div>
          </div>
          <div class="page" id="page-19">
              <div class="page-inner" ng-style="style()" resize><a href="#/home/page-20">Page 20</a></div>
          </div>
          <div class="page" id="page-20">
              <div class="page-inner" ng-style="style()" resize><a href="#/home/page-17">Page 17</a></div>
          </div>
    </script>

    <div class="wrapper">
      <div class="view" ng-view scroll></div>
    </div>
</body>

javascript:

var app = angular.module('app', []);

/*
  Controllers
*/
app.controller( 'appController', function( $scope ) {

});
app.controller( 'routeController', function( $scope, $routeParams ) {
  //When route change, check if page has been updated and run animateScroll directive
  if(typeof $routeParams !== 'undefined' && $routeParams.page.length > 0){
    $scope.animateScroll($routeParams.page);
  }
});

/*
  Page routes
*/
app.config(['$routeProvider',
  function($routeProvider) {
    $routeProvider.
      when('/home/:page', {
        templateUrl: 'home-template',
        controller: 'routeController'
      })

      .otherwise({
        redirectTo: '/home/'
      });
}]);

/*
  Directives
*/
app.directive('scroll', function ($routeParams, $timeout) {
  /* 
  Scroll to element ID
  */
  return {
    restrict: 'A',
    link: function(scope, elm, attrs) {
      scope.animateScroll = function(page) {
        $timeout(function(){
          console.log('test');
          if(jQuery('#' + page).length == 1){
            jQuery('html, body').animate({
              scrollTop:  jQuery('#' + page).position().top
            }); 
          };
        }, 1);
      };
    }
  };
});

app.directive('resize', function ($window) {
  return function (scope, element) {
    var w = angular.element($window);

    scope.getWindowDimensions = function () {
      return { height: w.height() };
    };

    scope.$watch(scope.getWindowDimensions, function (dimensions) {
        scope.windowHeight = dimensions.height;
        scope.style = function () {
          return { 
              'min-height': scope.windowHeight + 'px'
          };
        };
    }, true);

    w.bind('resize', function () {
      scope.$apply();
    });
  }
});

app.directive('a', function() {
  return {
    restrict: 'E',
    link: function(scope, elem, attrs) {
      elem.on('click', function(e){
        e.preventDefault();
      });
    }
  };
});

页面布局示例:

【问题讨论】:

    标签: jquery angularjs angularjs-directive angularjs-routing


    【解决方案1】:

    我不确定滚动是否应该与路由混合使用。我最好做这样的事情: 1.用ng-click代替href,和href="javascript:"(支持IE8需要) 2.使用接收元素id的向下滚动函数。

    下面的例子

    http://jsfiddle.net/naS4U/

    【讨论】:

    • 我有这种感觉。唯一的问题是,我需要 URL 链接到页面。
    • 啊,好吧,也许它看起来不太好,但是您可以在重定向到新 url 之前存储当前滚动位置,并且在重定向后立即将滚动移动到该位置,之后动画平滑滚动到所选页面。
    • 我刚遇到这个问题。我使用了 href="javascript:void()" title="#idvalue";这样,您也可以在旧浏览器中检索属性标题并按照您的喜好应用它
    • @CS,最好不要这样使用title属性,因为“#idvalue”会在悬停状态下显示,尝试使用data-link属性,或者其他一些data-*属性.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-16
    • 1970-01-01
    • 1970-01-01
    • 2012-03-25
    • 2014-10-23
    • 2011-10-25
    • 1970-01-01
    相关资源
    最近更新 更多