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

Andriy Drozdyuk
quelle
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.

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

Paola Cerioli
quelle
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>
Edmar Miyake
quelle
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;
  });
Rebecca
quelle
1

Ich hatte das gleiche Problem, aber das hat bei mir funktioniert:

<a ng-href="javascript:void(0);#tagId"></a>
Leonardo Silva do Nascimento
quelle
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>
Imran Omar Bukhsh
quelle
1

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

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

Farzad.Kamali
quelle
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

Marko
quelle
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.

Amay Kulkarni
quelle
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();
      });      
    }
  };
});
Márcio Marinho
quelle
0

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

$location.hash('id_in_html');
Vijay
quelle