2015-10-15 71 views
3

我期待有一个用户点击页面上的链接,这将触发一个stateChange并引导他们到一个新的状态。我想要达到的是状态完成加载后,然后滚动到上一页上链接指定的页面上的锚点。AngularJS:状态变化后自动滚动到锚点

要做到这一点我使用的传递$ stateParam通过组合的UI-S参考,像这样:

<a ui-sref="stateParent.stateChild({id: 'practiceParam'})">goToPage</a> 

然后当到达页面有一个div坐在上面附有一个指令激活$ viewContentLoaded,所以DOM被渲染,我可以搜索一个ID。在HTML DIV看起来是这样的:

<div scroll-after-load ></div> 

和我的滚动指令如下:

angular.module('app').directive('scrollAfterLoad', function() { 
    return { 
    restrict: 'A', 
    link: function(scope, $elm, attrs, $stateParams) { 
     scope.$on('$viewContentLoaded', function() { 
      console.log('scrollAfterLoad Directive Loaded, $stateParams are: ', $stateParams); 
      var idToScroll = attrs.href; 
      var $target; 
      if (idToScroll) { 
       $target = $(idToScroll); 
       // the -50 accounts for the top navbar which is fixed on the page and removed from pageflow 
       $("html,body").animate({scrollTop: $target.offset().top - 50}, "slow"); 
      } 
     }); 
    } 
    }; 
}); 

我还没有设置在格在href但因为我无法访问传递的参数困扰,很我访问不正确?我也尝试使用更加标准的state.go()传递一个stateParam,但是我的结果仍然为null。

一旦我可以通过一个stateparam,Idea只是添加一个href到注入到新加载的页面上的div的params,并自动滚动到该页面上的另一个div,其ID与我传递的参数匹配。

另外一个侧面说明,在我的ui-view上,我的autoscroll设置为true,所以页面自动加载到顶部,我喜欢这种行为,这是我需要状态来完成加载之前scoll被激活的原因。

+0

有趣的解决方案,但ID远离我的项目更多的依赖和写一个简单的指令。 – Eolis

回答

2

你的问题是,你正试图注入$stateParams服务到纽带作用。然而,这种注射的正确位置是工厂方法,意味着指令的定义。工厂方法已在模块中注册 - 与您的scrollAfterLoad指令相同。欲了解更多信息,请查询AngularJS Dependency Injection

所以回到你的问题:如果你真的注入$stateParams到你的指令的工厂方法,意味着在顶部你将能够轻松访问参数。您的指令可能是这样的:

angular.module('app').directive('scrollAfterLoad', ['$stateParams', function($stateParams) { 
    return { 
    restrict: 'A', 
    link: function(scope, $elm, attrs) { 
     scope.$on('$viewContentLoaded', function() { 
      console.log('scrollAfterLoad Directive Loaded, $stateParams are: ', $stateParams); 
      var idToScroll = attrs.href; 
      var $target; 
      if (idToScroll) { 
       $target = $(idToScroll); 
       // the -50 accounts for the top navbar which is fixed on the page and removed from pageflow 
       $("html,body").animate({scrollTop: $target.offset().top - 50}, "slow"); 
      } 
     }); 
    } 
    }; 
}]); 

注意,我已经从你的链接功能删除$stateParams并把它在顶部。这样服务将在链接功能中可用 - 实际上在整个指令中。

我在这Plunker转载您的方案。

+0

我看到了,这很有道理,并且我已经在我的项目中使用了参数。非常感谢你的帮助!希望我只是把一些东西放在错误的地方或不正确地使用这些参数。 – Eolis

2

随着angular-scroll你可以做这样的:

传递你scroll target id的状态参数子状态控制器,然后滚动到元素与scrollToAnimated(element)

如果您想让它可重用,您可以创建该控制器的工厂,并将其注入到子状态的解析中。这也应该工作,但我还没有测试过。

如果您处于子状态并再次单击状态更改链接,您可能需要重新滚动滚动。这就是为什么我添加了方法checkState,重新加载当前状态,如果我们在子状态重复滚动。

请看下面的演示或在这fiddle

我认为你的指令不起作用,因为你没有将href属性传递给你的指令。

您可以通过将href="targetId"传递给您的指令来解决此问题,其中targetId在您的子控制器中添加了$scope.targetId = $stateParams.id。或者,如果您不使用隔离范围,则可以直接访问targetId$scope

无论如何,我会这样做,就像我在演示中或与工厂内部的解决方案一样。

angular.module('demoApp', ['ui.router', 'duScroll']) 
 
\t .controller('MainControlller', MainController) 
 
\t .config(Config); 
 

 
function MainController($scope, $state) { 
 
\t $scope.checkState = function() { 
 
    \t //console.log($state.current); 
 
     if($state.current.name == 'parent.child') { 
 
      //console.log('parent.child state'); 
 
     \t // reload to retrigger scrolling again 
 
      $state.reload(); 
 
     } 
 
    }; 
 
} 
 

 
function Config($urlRouterProvider, $stateProvider) { 
 
\t $urlRouterProvider.otherwise('/'); 
 
    
 
    $stateProvider 
 
    \t .state('parent', { 
 
     \t url: '/', 
 
     \t templateUrl: 'home.html' 
 
    }) 
 
    \t .state('parent.child', { 
 
    \t url: 'child/:id', 
 
     templateUrl: 'child.html', 
 
     controller: function($scope, $stateParams, $document) { 
 
     \t var scrollElement = angular 
 
       .element(document.getElementById($stateParams.id)); 
 
      console.log(scrollElement); 
 
      $document.scrollToElementAnimated(scrollElement); 
 
     } 
 
    }); 
 
       
 
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-scroll/0.7.3/angular-scroll.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.js"></script> 
 
<div ng-app="demoApp" ng-controller="MainController"> 
 
    <script type="text/ng-template" id="home.html"> 
 
     <a ui-sref="parent.child({id: 'practiceParam'})" ng-click="checkState()">go to practice</a> 
 
     <div ui-view=""></div> 
 
    </script> 
 
    <script type="text/ng-template" id="child.html"> 
 
     <!--<a href="#practiceParam" du-smooth-scroll="">scroll to practice</a> 
 
     --><p> 
 
      Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. 
 
     </p><p> 
 
Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. 
 
     </p><p> 
 
Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.</p> 
 
<p> 
 
Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. 
 
     </p> 
 
     <p> 
 
      Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. 
 
     </p> 
 
     <h1 id="practiceParam">practice</h1> 
 
     <p> 
 
Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. 
 
     </p><p> 
 
Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.</p> 
 
<p> 
 
Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. 
 
     </p> 
 
     <a ui-sref="parent">back</a> 
 
    </script> 
 
    
 
    <div ui-view=""></div> 
 
</div>