Ankerverbindungen in Angularjs?


78

Ist es möglich, Ankerverbindungen mit Angularjs zu verwenden?

Dh:

 <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>

Vielen Dank


13
Nun, Angularjs fängt diese Links ab und leitet sie durch sein eigenes Routing-System ...
Andriy Drozdyuk

Antworten:


105

Es gibt einige Möglichkeiten, dies zu tun, wie es scheint.

Option 1: Native Angular

Angular bietet einen $anchorScrollService an, aber die Dokumentation fehlt stark und ich konnte sie nicht zum Laufen bringen.

Unter http://www.benlesh.com/2013/02/angular-js-scrolling-to-element-by-id.html finden Sie einige Einblicke in $anchorScroll.

Option 2: Benutzerdefinierte Direktive / natives JavaScript

Eine andere Möglichkeit, die ich getestet habe, war das Erstellen einer benutzerdefinierten Direktive und deren Verwendung el.scrollIntoView(). Dies funktioniert ziemlich anständig, indem Sie in Ihrer Direktiven-Link-Funktion im Grunde Folgendes tun:

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

Es scheint jedoch etwas übertrieben, beides zu tun, wenn der Browser dies nativ unterstützt, oder?

Option 3: Angular Override / Native Browser

Wenn Sie sich http://docs.angularjs.org/guide/dev_guide.services.$location und den Abschnitt zum Umschreiben von HTML-Links ansehen , werden Sie feststellen, dass Links im Folgenden nicht neu geschrieben werden:

Links, die Zielelemente enthalten

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

Alles, was Sie tun müssen, ist das targetAttribut zu Ihren Links hinzuzufügen , wie folgt :

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

Angular verwendet standardmäßig den Browser. Da es sich um einen Ankerlink und nicht um eine andere Basis-URL handelt, scrollt der Browser wie gewünscht zum richtigen Speicherort.

Ich habe mich für Option 3 entschieden, weil es am besten ist, sich hier auf native Browserfunktionen zu verlassen, und uns Zeit und Mühe spart.

Ich muss beachten, dass Angular nach einer erfolgreichen Änderung von Bildlauf und Hash den Hash weiterverfolgt und in seinen benutzerdefinierten Stil umschreibt. Der Browser hat sein Geschäft jedoch bereits abgeschlossen und Sie können loslegen.


1
Leider gibt es viele übrig gebliebene Nebenwirkungen durch den zusätzlichen Hash in der Adressleiste. Ich fand Option 2 hier viel effektiver. Jemand hat bereits die Anweisung geschrieben, um zu booten: ngmodules.org/modules/ngScrollTo
Riley Lark

Option 2 ist hier definitiv die einfachste, insbesondere wenn Sie Routing verwenden. Ich hatte ein Problem mit geschichteten Registerkarten mit Bootstrap, und Opt2 machte es einfach dumm. Vielen Dank
Dameo

4
Es gibt ein Problem beim Setzen von target = "_ self". Wenn ich jemandem so etwas wie diesen Link stackoverflow.com/#footer gebe , navigiert er nicht zur Fußzeile. Sie navigieren nur zur Fußzeile, wenn Sie auf <a href="#footer" target="_self"> Zur Fußzeile gehen </a> klicken. Irgendein Ideal? Dies ist wichtig, da ich meinem Freund normalerweise einen solchen Link gebe, um zu zeigen, auf welchen Teil er sich konzentrieren muss.
Ryan

3
Leider leitet mich Option 3 zum Stammverzeichnis der Website weiter .ie localhost: 9000 / # medical anstelle von localhost: 9000 / # / case / 1 # medical . sogar mit dem _self Ziel.
Rafael

1
Option 3 funktionierte hervorragend für einen Link "Zum Inhalt springen"! Vielen Dank!
Lane Sawyer

27

Ich weiß nicht, ob das Ihre Frage beantwortet, aber ja, Sie können eckige Links verwenden, wie zum Beispiel:

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

Auf der AngularJS-Website gibt es ein gutes Beispiel:

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

UPDATE: Die AngularJS-Dokumentation war etwas dunkel und bot keine gute Lösung dafür. Es tut uns leid!

Eine bessere Lösung finden Sie hier: So behandeln Sie die Anker-Hash-Verknüpfung in AngularJS


Ich auch nicht @drozzy: Können Sie uns bitte sagen, welche Version von AngularJS Sie verwendet haben? danke
Anas

1
Der Trick besteht darin, ein leeres href-Attribut zu haben. Macht ihr das?
Andriy Drozdyuk

1
Wo ist dokumentiert, dass wir neben ng-href auch eine leere href benötigen?
Alearg

Dieser zweite Link hat funktioniert. Sie müssen sich nicht einmal um das Routing kümmern, wenn er sich auf derselben Seite befindet. Hat super funktioniert.
Mastro

24

Sie könnten versuchen, anchorScroll zu verwenden .

Beispiel

Der Controller wäre also:

app.controller('MainCtrl', function($scope, $location, $anchorScroll, $routeParams) {
  $scope.scrollTo = function(id) {
     $location.hash(id);
     $anchorScroll();
  }
});

Und die Aussicht:

<a href="" ng-click="scrollTo('foo')">Scroll to #foo</a>

... und kein Geheimnis für die Anker-ID:

<div id="foo">
  This is #foo
</div>

2
Hinweis: Der $anchorScroll()Anruf nach dem $location.hash()Anruf ist nicht erforderlich, da er automatisch $anchorScrollüberwacht $location.hash().
PLPeeters

Die Dokumente rufen in ihrem Beispiel $ anchorScroll () auf, aber @Edmar, Sie haben Recht, Sie lassen immer $anchorScroll()noch einen Bildlauf zum neuen Speicherort aus.
Twknab

7

$ anchorScroll ist zwar die Antwort darauf, aber es gibt eine viel bessere Möglichkeit, es in neueren Versionen von Angular zu verwenden.

Jetzt akzeptiert $ anchorScroll den Hash als optionales Argument, sodass Sie $ location.hash überhaupt nicht ändern müssen. ( Dokumentation )

Dies ist die beste Lösung, da sie die Route überhaupt nicht beeinflusst. Ich konnte keine der anderen Lösungen zum Laufen bringen, da ich ngRoute verwende und die Route neu geladen wird, sobald ich sie festgelegt habe $location.hash(id), bevor $ anchorScroll ihre Magie entfalten kann.

So verwenden Sie es ... zuerst in der Direktive oder im Controller:

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

und dann in der Ansicht:

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

Wenn Sie eine feste Navigationsleiste (oder eine andere Benutzeroberfläche) berücksichtigen müssen, können Sie den Offset für $ anchorScroll wie folgt festlegen (in der Ausführungsfunktion des Hauptmoduls):

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


1

Funktioniert bei mir:

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

1

Sie müssen Ihrem Link nur target = "_ self" hinzufügen

Ex. <a href="#services" target="_self">Services</a><div id="services"></div>


Getestet auf angular.js / 1.6.10 und funktioniert gut, um klarer zu machen, habe ich die Antwort bearbeitet
Farzad.Kamali

könnte etwas sein, das vielleicht einen Konflikt verursacht? Ich habe genau den gleichen Code
Dani

0

Oder Sie könnten einfach schreiben:

ng-href="\#yourAnchorId"

Bitte beachten Sie den Backslash vor dem Hash-Symbol


Nein, ich habe diese Lösung nur zufällig gefunden.
Marko

Hat jemand getestet, ob dies funktioniert oder ob dies funktionieren soll?
JustGoscha

ng-href="##anchorId"funktioniert bei mir (Angular 1.2.21). Das ist mir aufgefallen, dass $ location.hash ('anchorId') dies tut.
PSWai

9
ng-href = "\ # myAnchorTag" funktionierte weder für mich noch ng-href = "## anchorId"
mcgraw

0

Wenn Sie SharePoint und Angular verwenden, gehen Sie wie folgt vor:

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

Dabei ist LinkTo und Titel die SharePoint-Spalte.


0

Die beste Wahl für mich war, eine Direktive zu erstellen, um die Arbeit zu erledigen, da $location.hash()und $anchorScroll()die URL zu entführen, was viele Probleme mit meinem SPA-Routing verursacht.

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

Sie können auch vom Controller aus zur HTML-ID navigieren

$location.hash('id_in_html');
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.