有人知道如何在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可以解决这个问题,但在Angular的最新版本中,有更好的方法来使用它。

现在,$anchorScroll接受散列作为可选参数,因此您不必更改$location。完全是散列。(文档)

这是最好的解决方案,因为它完全不影响路线。我不能得到任何其他解决方案的工作,因为我使用ngRoute和路由将重新加载,只要我设置$location.hash(id),之前$anchorScroll可以做它的魔法。

下面是如何使用它…首先,在指令或控制器中:

$scope.scrollTo = function (id) {
  $anchorScroll(id);  
}

然后在视图中:

<a href="" ng-click="scrollTo(id)">Text</a>

同样,如果你需要考虑一个固定的导航栏(或其他UI),你可以像这样设置$anchorScroll的偏移量(在主模块的run函数中):

.run(function ($anchorScroll) {
   //this will make anchorScroll scroll to the div minus 50px
   $anchorScroll.yOffset = 50;
});

其他回答

不需要更改任何路由或其他任何东西,只需要在创建链接时使用target="_self"

例子:

<a href="#faq-1" target="_self">Question 1</a>
<a href="#faq-2" target="_self">Question 2</a>
<a href="#faq-3" target="_self">Question 3</a>

在你的html元素中使用id属性,就像这样:

<h3 id="faq-1">Question 1</h3>
<h3 id="faq-2">Question 2</h3>
<h3 id="faq-3">Question 3</h3>

在注释中没有必要使用##;-)

上面的方法对我都没用,但我刚试了一下,而且很管用,

<a href="#/#faq-1">Question 1</a>

所以我意识到我需要通知页面从索引页开始,然后使用传统的锚。

在我的脑海中@ slugsllog已经有了,但我要改变一件事。我会用replace代替,这样你就不用回调了。

$scope.scrollTo = function(id) {
    var old = $location.hash();
    $location.hash(id).replace();
    $anchorScroll();
};

文档搜索“替换方法”

<a href="/#/#faq-1">Question 1</a>
<a href="/#/#faq-2">Question 2</a>
<a href="/#/#faq-3">Question 3</a>

我可以这样做:

<li>
<a href="#/#about">About</a>
</li>