【问题标题】:Anchor links in Angularjs?Angularjs中的锚链接?
【发布时间】:2012-12-11 04:22:27
【问题描述】:

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>

谢谢

【问题讨论】:

  • 嗯,Angularjs 会拦截这些链接并通过它自己的路由系统路由它们...

标签: angularjs


【解决方案1】:

似乎有几种方法可以做到这一点。

选项 1:原生 Angular

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 链接重写部分,您会发现链接未在以下内容中重写:

包含目标元素的链接

示例:&lt;a href="/ext/link?a=b" target="_self"&gt;link&lt;/a&gt;

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

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

Angular 默认使用浏览器,因为它是一个锚链接而不是不同的基本 url,浏览器会根据需要滚动到正确的位置。

我选择了选项 3,因为它最好在这里依赖本机浏览器功能,并且可以节省我们的时间和精力。

需要注意的是,在成功滚动和散列更改后,Angular 会跟进并将散列重写为其自定义样式。但是,浏览器已经完成了它的业务,你可以开始了。

【讨论】:

  • 不幸的是,地址栏中的额外哈希有很多剩余的副作用。我发现这里的选项 2 更有效。有人已经编写了启动指令:ngmodules.org/modules/ngScrollTo
  • 这里的选项 2 绝对是最简单的,尤其是在使用路由的情况下。我在使用 Bootstrap 时遇到了分层选项卡的问题,而 Opt2 让它变得非常简单。谢谢
  • 设置 target="_self" 有一个问题。如果我给某人这样的链接 stackoverflow.com/#footer ,它不会导航到页脚。如果您单击 Go to Footer,它只会导航到页脚。有理想吗?这很重要,因为我通常会给我的朋友一个这样的链接,以显示他/她需要关注的部分。
  • 不幸的是,选项 3 会将我重定向到网站的根目录。即localhost:9000/#medical 而不是 localhost:9000/#/case/1#medical。即使是 _self 目标。
  • 选项 3 非常适合“跳转到内容”链接!谢谢!
【解决方案2】:

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

&lt;a ng-href="http://www.gravatar.com/avatar/{{hash}}"/&gt;

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

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

更新:AngularJS 文档有点晦涩难懂,也没有提供好的解决方案。对不起!

您可以在这里找到更好的解决方案:How to handle anchor hash linking in AngularJS

【讨论】:

  • 我也不是@drozzy:你能告诉我们你使用的是哪个版本的AngularJS吗?谢谢
  • 诀窍是有一个 empty href 属性。你们这样做吗?
  • 在哪里记录了 除了 使用 ng-href 我们还需要有一个空的 href?
  • 第二个链接有效,如果它在同一页面上,您甚至无需担心路由。效果很好。
【解决方案3】:

您可以尝试使用anchorScroll

Example

所以控制器是:

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>

【讨论】:

  • 注意:$location.hash() 调用之后的$anchorScroll() 调用是不必要的,因为$anchorScroll 会自动监视$location.hash()。
  • 文档在他们的示例中调用$anchorScroll(),但@Edmar 你是对的,省略$anchorScroll() 仍会滚动到新位置。
【解决方案4】:

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

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

这是最好的解决方案,因为它根本不影响路线。我无法让任何其他解决方案发挥作用,因为我正在使用 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;
  });

【讨论】:

    【解决方案5】:

    我遇到了同样的问题,但这对我有用:

    <a ng-href="javascript:void(0);#tagId"></a>
    

    【讨论】:

      【解决方案6】:

      为我工作:

       <a onclick='return false;' href="" class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" ng-href="#profile#collapse{{$index}}"> blalba </a>
      

      【讨论】:

        【解决方案7】:

        您只需将 target="_self" 添加到您的链接中

        例如。 &lt;a href="#services" target="_self"&gt;Services&lt;/a&gt;&lt;div id="services"&gt;&lt;/div&gt;

        【讨论】:

        • 在 angular.js/1.6.10 上测试并且工作正常,为了更清楚,我编辑了答案
        • 可能会造成一些冲突?我有完全相同的代码
        【解决方案8】:

        或者你可以简单地写:

        ng-href="\#yourAnchorId"

        请注意井号前面的反斜杠

        【讨论】:

        • 不,我只是偶然想到了这个解决方案。
        • 有没有人测试过这是否有效,或者这是否应该有效?
        • ng-href="##anchorId" 为我工作(Angular 1.2.21)。这就是我注意到 $location.hash('anchorId') 所做的事情。
        • ng-href="\#myAnchorTag" 对我不起作用,ng-href="##anchorId"
        【解决方案9】:

        如果您使用的是 SharePoint 和 Angular,请按以下方式操作:

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

        在哪里 LinkTo 和 Title 是 SharePoint 列。

        【讨论】:

          【解决方案10】:

          对我来说最好的选择是创建一个指令来完成这项工作,因为$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();
                });      
              }
            };
          });
          

          【讨论】:

            【解决方案11】:

            您还可以从控制器内部导航到 HTML id

            $location.hash('id_in_html');
            

            【讨论】:

              猜你喜欢
              • 2016-09-08
              • 2014-12-20
              • 2013-01-20
              • 2012-07-25
              • 2013-01-08
              • 2011-10-15
              • 1970-01-01
              相关资源
              最近更新 更多