有人知道如何在AngularJS中很好地处理锚散列链接吗?
对于一个简单的faq页面,我有以下标记
<a href="#faq-1">Question 1</a>
<a href="#faq-2">Question 2</a>
<a href="#faq-3">Question 3</a>
<h3 id="faq-1">Question 1</h3>
<h3 id="faq-2">Question 2</h3>
<h3 id="fa1-3">Question 3</h3>
当点击上面的任何链接时,AngularJS会拦截并将我路由到一个完全不同的页面(在我的例子中,一个404页,因为没有路由匹配这些链接)。
我的第一个想法是创建一个匹配“/faq/:chapter”的路由,并在相应的控制器中检查$routeParams。然后使用jQuery向下滚动到它。
但是AngularJS又把我搞砸了,反正就是滚动到页面顶部。
有人在过去做过类似的事情并且知道一个好的解决方法吗?
编辑:切换到html5Mode应该解决我的问题,但我们有点必须支持IE8+无论如何,所以我担心这不是一个可接受的解决方案:/
您正在寻找$anchorScroll()。
这是(蹩脚的)文档。
这是来源。
基本上你只需要注入它并在控制器中调用它,它就会滚动到$location。hash()中id为的任何元素
app.controller('TestCtrl', function($scope, $location, $anchorScroll) {
$scope.scrollTo = function(id) {
$location.hash(id);
$anchorScroll();
}
});
<a ng-click="scrollTo('foo')">Foo</a>
<div id="foo">Here you are</div>
这里有一个活塞来演示
EDIT:用于路由
像往常一样设置angular路由,然后添加以下代码。
app.run(function($rootScope, $location, $anchorScroll, $routeParams) {
//when the route is changed scroll to the proper element.
$rootScope.$on('$routeChangeSuccess', function(newRoute, oldRoute) {
$location.hash($routeParams.scrollTo);
$anchorScroll();
});
});
你的链接应该是这样的:
<a href="#/test?scrollTo=foo">Test/Foo</a>
这是一个Plunker演示滚动路由和$anchorScroll
更简单的是:
app.run(function($rootScope, $location, $anchorScroll) {
//when the route is changed scroll to the proper element.
$rootScope.$on('$routeChangeSuccess', function(newRoute, oldRoute) {
if($location.hash()) $anchorScroll();
});
});
你的链接应该是这样的:
<a href="#/test#foo">Test/Foo</a>
你可以尝试使用anchorScroll。
例子
所以控制器会是:
app.controller('MainCtrl', function($scope, $location, $anchorScroll, $routeParams) {
$scope.scrollTo = function(id) {
$location.hash(id);
$anchorScroll();
}
});
和视图:
<a href="" ng-click="scrollTo('foo')">Scroll to #foo</a>
...锚的id也没有秘密:
<div id="foo">
This is #foo
</div>
如果你不喜欢使用ng-click,这里有一个替代解决方案。它使用过滤器根据当前状态生成正确的url。我的例子使用ui.router。
这样做的好处是用户可以在鼠标悬停时看到链接的位置。
<a href="{{ 'my-element-id' | anchor }}">My element</a>
过滤器:
.filter('anchor', ['$state', function($state) {
return function(id) {
return '/#' + $state.current.url + '#' + id;
};
}])