有人知道如何在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+无论如何,所以我担心这不是一个可接受的解决方案:/


当前回答

见https://code.angularjs.org/1.4.10/docs/api/ngRoute/provider/ routeProvider美元

[reloadOnSearch=true] - {boolean=} -仅当$location.search()或$location.hash()发生变化时重新加载路由。

对我来说,把这个设置为false就可以了。

其他回答

在我的例子中,我注意到如果修改$location.hash(),路由逻辑就开始起作用了。下面的技巧奏效了。

$scope.scrollTo = function(id) {
    var old = $location.hash();
    $location.hash(id);
    $anchorScroll();
    //reset to old to keep any additional routing logic from kicking in
    $location.hash(old);
};

这可能是ngView的一个新属性,但我已经能够使用ngView autoscroll属性和'double-hashes'让它锚定哈希链接与angular-route一起工作。

ngView(见autoscroll)

(以下代码用于角钢带)

<!-- use the autoscroll attribute to scroll to hash on $viewContentLoaded -->    
<div ng-view="" autoscroll></div>

<!-- A.href link for bs-scrollspy from angular-strap -->
<!-- A.ngHref for autoscroll on current route without a location change -->
<ul class="nav bs-sidenav">
  <li data-target="#main-html5"><a href="#main-html5" ng-href="##main-html5">HTML5</a></li>
  <li data-target="#main-angular"><a href="#main-angular" ng-href="##main-angular" >Angular</a></li>
  <li data-target="#main-karma"><a href="#main-karma" ng-href="##main-karma">Karma</a></li>
</ul>

我可以这样做:

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

我不能100%确定这是否一直工作,但在我的应用程序中,这给了我预期的行为。

假设你在ABOUT页面,你有以下路由:

yourApp.config(['$routeProvider', 
    function($routeProvider) {
        $routeProvider.
            when('/about', {
                templateUrl: 'about.html',
                controller: 'AboutCtrl'
            }).
            otherwise({
                redirectTo: '/'
            });
        }
]);

现在,在HTML中

<ul>
    <li><a href="#/about#tab1">First Part</a></li>
    <li><a href="#/about#tab2">Second Part</a></li>
    <li><a href="#/about#tab3">Third Part</a></li>                      
</ul>

<div id="tab1">1</div>
<div id="tab2">2</div>
<div id="tab3">3</div>

总之

在锚点之前包含页面名称对我来说很有用。 让我知道你的想法。

缺点

这将重新呈现页面,然后滚动到锚点。

更新

更好的方法是添加以下内容:

<a href="#tab1" onclick="return false;">First Part</a>

不需要更改任何路由或其他任何东西,只需要在创建链接时使用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>

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