Angularjs中的锚链接?


78

是否可以在Angularjs中使用锚链接?

即:

 <a href="#top">Top</a>
 <a href="#middle">Middle</a>
 <a href="#bottom">Bottom</a>

 <div name="top"></div>
 ...
 <div name="middle"></div>
 ...
 <div name="bottom"></div>

谢谢


13
好吧,Angularjs拦截了这些链接,并通过它自己的路由系统对其进行了路由……
Andriy Drozdyuk

Answers:


105

看来有几种方法可以做到这一点。

选项1:本机角度

Angular提供了一项$anchorScroll服务,但是严重缺乏文档,我无法使其正常工作。

请访问http://www.benlesh.com/2013/02/angular-js-scrolling-to-element-by-id.html,以获取有关的一些见解$anchorScroll

选项2:自定义指令/本机JavaScript

我测试的另一种方法是创建自定义指令并使用el.scrollIntoView()。通过基本上在指令链接函数中执行以下操作,此方法相当不错:

var el = document.getElementById(attrs.href);
el.scrollIntoView();

但是,当浏览器本机支持这两个功能时,同时执行这两个操作似乎有点过头了,对吧?

选项3:角度覆盖/本机浏览器

如果您看一下http://docs.angularjs.org/guide/dev_guide.services.$location及其“ HTML链接重写”部分,您会发现以下内容未重写链接:

包含目标元素的链接

例: <a href="https://stackoverflow.com/ext/link?a=b" target="_self">link</a>

因此,您要做的就是将target属性添加到链接中,如下所示:

<a href="#anchorLinkID" target="_self">Go to inpage section</a>

Angular默认为浏览器,由于它是锚链接而不是其他基本URL,因此浏览器可根据需要滚动到正确的位置。

我之所以选择选项3,是因为它最好地依靠此处的本机浏览器功能,从而节省了我们的时间和精力。

要注意的是,在成功完成滚动和哈希更改之后,Angular会继续跟踪并将哈希重写为其自定义样式。但是,浏览器已经完成其业务,您一切顺利。


1
不幸的是,地址栏中多余的哈希值会带来许多剩余的副作用。我发现这里的选项2更有效。有人已经写了该指令来引导:ngmodules.org/modules/ngScrollTo
Riley Lark

选项2绝对是最简单的选项,尤其是在使用路由的情况下。我在使用Bootstrap的分层选项卡时遇到问题,而Opt2使其变得愚蠢。谢谢
Dameo 2014年

4
设置target =“ _ self”存在一个问题。如果我给某人这样的链接stackoverflow.com/#footer,它将不会导航到页脚。如果您单击<a href="#footer" target="_self">转到页脚</a>,它将仅导航到页脚。有理想吗?这很重要,因为我通常会给我的朋友这样的链接,以显示他/她需要关注的部分。
瑞安

3
不幸的是,选项3会将我重定向到网站的根目录,即localhost:9000 /#medical而不是localhost:9000 /#/ case / 1#medical。即使使用_self目标。
拉斐尔

1
选项3在“跳至内容”链接方面表现出色!谢谢!
Lane Sawyer

27

我不知道是否能回答您的问题,但是可以,您可以使用angularjs链接,例如:

<a ng-href="http://www.gravatar.com/avatar/{{hash}}"/>

AngularJS网站上有一个很好的例子:

http://docs.angularjs.org/api/ng.directive:ngHref

更新:AngularJS文档有点晦涩难懂,并且没有提供一个很好的解决方案。抱歉!

您可以在此处找到更好的解决方案:如何在AngularJS中处理锚点哈希链接


我也不是@drozzy:您能告诉我们您使用的是哪个版本的AngularJS吗?谢谢
Anas 2013年

1
诀窍是拥有一个空的href属性。你们在这样做吗?
Andriy Drozdyuk

1
在哪里记录着,除了使用ng-href之外,我们还需要有一个空的href?
alearg

第二个链接有效,如果它在同一页面上,您甚至不必担心路由。很棒。
马斯特罗

24

您可以尝试使用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>

2
注意:$anchorScroll()下面的调用$location.hash()呼叫是不必要的,因为$anchorScroll手表$location.hash自动地()。
PLPeeters

在他们的示例中,文档调用$ anchorScroll(),但@Edmar是正确的,省略了$anchorScroll()仍会滚动到新位置。
twknab

7

$ anchorScroll确实是解决这个问题的方法,但是在更新的Angular版本中有更好的方法来使用它。

现在,$ anchorScroll接受哈希作为可选参数,因此您根本不必更改$ location.hash。(文件

这是最好的解决方案,因为它根本不影响路由。我无法使用其他任何解决方案,因为我使用的是ngRoute,并且路由会在设置$location.hash(id)$ anchorScroll发挥作用之前尽快重新加载。

这是如何使用它...首先,在指令或控制器中:

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

然后在视图中:

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

另外,如果您需要考虑固定的导航栏(或其他UI),则可以这样设置$ anchorScroll的偏移量(在主模块的运行功能中):

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



1

您只需要在链接中添加target =“ _ self”

例如 <a href="#services" target="_self">Services</a><div id="services"></div>


在angular.js / 1.6.10上进行了测试,并且工作正常,为了更加清楚,我编辑了答案
Farzad.Kamali

可能会引起一些冲突?我有完全相同的代码
达尼

0

或者您可以简单地写:

ng-href="\#yourAnchorId"

请注意井号前面的反斜杠


不,我只是偶然提出了这个解决方案。
Marko 2014年

有没有人测试过这种方法是否可行,或者是否应该可行?
JustGoscha 2014年

ng-href="##anchorId"为我工作(角度1.2.21)。这就是我注意到$ location.hash('anchorId')所做的事情。
PSWai 2014年

9
NG-HREF = “\#myAnchorTag”没有工作对我来说也没有NG-HREF = “## anchorId”
麦格劳

0

如果您使用的是SharePoint和angular,请按照以下步骤操作:

<a ng-href="{{item.LinkTo.Url}}" target="_blank" ng-bind="item.Title;" ></a> 

其中“链接到”和“标题”是“ SharePoint列”。


0

对我而言,最好的选择是创建一个指令来完成工作,因为$location.hash()$anchorScroll()劫持URL会给我的SPA路由造成很多问题。

MyModule.directive('myAnchor', function() {
  return {
    restrict: 'A',
    require: '?ngModel',
    link: function(scope, elem, attrs, ngModel) {
      return elem.bind('click', function() {
        //other stuff ...
        var el;
        el = document.getElementById(attrs['myAnchor']);
        return el.scrollIntoView();
      });      
    }
  };
});

0

您也可以从控制器内部导航到HTML ID

$location.hash('id_in_html');
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.