Umgang mit Anker-Hash-Verknüpfungen in AngularJS

318

Weiß jemand von euch, wie man mit Anker-Hash-Verknüpfungen in AngularJS gut umgeht ?

Ich habe das folgende Markup für eine einfache FAQ-Seite

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

Wenn Sie auf einen der oben genannten Links klicken, fängt AngularJS mich ab und leitet mich zu einer völlig anderen Seite weiter (in meinem Fall zu einer 404-Seite, da keine Routen zu den Links passen).

Mein erster Gedanke war, eine Routenübereinstimmung " / faq /: kapitel " zu erstellen und in der entsprechenden Steuerung $routeParams.chapternach einem übereinstimmenden Element zu prüfen und dann mit jQuery nach unten zu scrollen.

Aber dann scheißt AngularJS wieder auf mich und scrollt trotzdem einfach zum Anfang der Seite.

Also hat hier jemand in der Vergangenheit etwas Ähnliches getan und kennt eine gute Lösung dafür?

Bearbeiten: Der Wechsel zu html5Mode sollte meine Probleme lösen, aber wir müssen trotzdem IE8 + unterstützen, daher befürchte ich, dass dies keine akzeptierte Lösung ist: /

Rasmus
quelle
Ich denke, eckig schlägt vor, ng-href=""stattdessen zu verwenden .
Huckepack
10
Ich denke, ng-href ist nur anwendbar, wenn die URL dynamische Daten enthält, die an ein ng-Modell gebunden werden müssen. Ich frage mich, ob Sie dem locationProvider ein HashPrefix zuweisen, wenn er die Links zu den IDs ignoriert: docs.angularjs.org/guide/dev_guide.services.$location
Adam
Adam hat Recht mit der Verwendung von ng-href.
Rasmus
Mögliches Duplikat von Anchor-Links in Angularjs?
Michaël Benjamin Saerens
Dies ist auch ein Problem für neue Angular: stackoverflow.com/questions/36101756/…
phil294

Antworten:

374

Du suchst $anchorScroll().

Hier ist die (beschissene) Dokumentation.

Und hier ist die Quelle.

Grundsätzlich injizieren Sie es einfach und rufen es in Ihrem Controller auf, und es führt Sie zu einem beliebigen Element mit der darin gefundenen ID $location.hash()

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

<a ng-click="scrollTo('foo')">Foo</a>

<div id="foo">Here you are</div>

Hier ist ein Plunker zu demonstrieren

BEARBEITEN: um dies beim Routing zu verwenden

Richten Sie Ihr Winkelrouting wie gewohnt ein und fügen Sie dann einfach den folgenden Code hinzu.

app.run(function($rootScope, $location, $anchorScroll, $routeParams) {
  //when the route is changed scroll to the proper element.
  $rootScope.$on('$routeChangeSuccess', function(newRoute, oldRoute) {
    $location.hash($routeParams.scrollTo);
    $anchorScroll();  
  });
});

und dein Link würde so aussehen:

<a href="#/test?scrollTo=foo">Test/Foo</a>

Hier ist ein Plunker, der das Scrollen mit Routing und $ anchorScroll demonstriert

Und noch einfacher:

app.run(function($rootScope, $location, $anchorScroll) {
  //when the route is changed scroll to the proper element.
  $rootScope.$on('$routeChangeSuccess', function(newRoute, oldRoute) {
    if($location.hash()) $anchorScroll();  
  });
});

und dein Link würde so aussehen:

<a href="#/test#foo">Test/Foo</a>
Ben Lesh
quelle
5
Beim Hinzufügen von Routing kann ein Problem auftreten: Wenn Sie ngView hinzufügen, würde jede Änderung des URL-Hash ein erneutes Laden der Route auslösen ... In Ihrem Beispiel gibt es kein Routing und die URL spiegelt nicht das aktuelle Element wider ... Aber danke, dass Sie auf $ anchorScroll
Valentyn Shybanov verweisen
1
@blesh: Wenn Sie location.hash (X) aufrufen, wird die Seite geändert, da das Routing die Ansichten steuert.
dsldsl
24
Diese Lösung bewirkt, dass meine gesamte Anwendung neu gerendert wird.
2
@dsldsl && @OliverJosephAsh: $ location.hash () lädt die Seite nicht neu. Wenn ja, ist noch etwas los. Hier ist derselbe Plunk mit der Zeit, die beim Laden der Seite ausgeschrieben wird. Sie werden sehen, dass sich nichts ändert. Wenn Sie zu einem Ankertag auf der aktuellen Seite scrollen möchten, ohne die Route neu zu laden, führen Sie einfach eine aus regulärer Link <a href="#foo">foo</a>. Mein Codebeispiel bestand darin, das Scrollen zu einer ID beim Routenwechsel anzuzeigen.
Ben Lesh
4
@blesh: Ich würde empfehlen, dass Sie den Hash auch entfernen, nachdem Sie zum gewünschten Abschnitt gescrollt haben. Auf diese Weise wird die URL nicht mit Dingen verschmutzt, die eigentlich nicht vorhanden sein sollten. Verwenden Sie dies: $location.search('scrollTo', null)
Kumarharsh
168

In meinem Fall habe ich festgestellt, dass die Routing-Logik aktiviert wurde, wenn ich die geändert habe $location.hash(). Der folgende Trick hat funktioniert ..

$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);
};
slugslog
quelle
5
Genialer Dank dafür, die Routing-Logik hat sich absolut geweigert, sich zu verhalten, selbst wenn die .run (...) -Lösung von @ blesh verwendet wurde, und das sortiert sie.
ljs
8
Ihr Trick, den alten Hash zu retten, war ein absoluter Lebensretter. Es verhindert das erneute Laden der Seite, während die Route sauber bleibt. Tolle Idee!
ThisLanham
2
Schön. Nach der Implementierung Ihrer Lösung aktualisiert die URL jedoch nicht den Wert der Ziel-ID.
Mohamed Hussain
1
Ich hatte die gleiche Erfahrung wie Mohamed ... Es hat zwar das Nachladen gestoppt, aber es zeigt die hashless-Route an (und $ anchorScroll hatte keine Auswirkung). 1.2.6 Hmmmm.
Michael
3
Ich benutze $location.hash(my_id); $anchorScroll; $location.hash(null). Es verhindert das Neuladen und ich muss die oldVariable nicht verwalten .
MFB
53

Es ist nicht erforderlich, das Routing oder andere Elemente zu ändern, die nur zum target="_self"Erstellen der Links verwendet werden müssen

Beispiel:

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

Und verwenden Sie das idAttribut in Ihren HTML- Elementen wie folgt:

<h3 id="faq-1">Question 1</h3>
<h3 id="faq-2">Question 2</h3>
<h3 id="faq-3">Question 3</h3>

Es ist nicht erforderlich, ## zu verwenden, wie in den Kommentaren angegeben / erwähnt ;-)

Mauricio Gracia Gutierrez
quelle
1
Dies hat bei mir nicht funktioniert, aber die Lösung hier hat funktioniert: stackoverflow.com/a/19367249/633107
Splaktar
6
Danke für diese Lösung. Aber target = "_ self" ist ausreichend. Keine Notwendigkeit, # zu verdoppeln
Christophe P
5
target = "_ self" ist definitiv die beste Antwort (keine Notwendigkeit, # zu verdoppeln, wie von Christophe P hervorgehoben). Dies funktioniert unabhängig davon, ob Html5Mode aktiviert oder deaktiviert ist.
Newman
3
Einfach und vollständig. Arbeitete für mich, ohne eine weitere Winkelabhängigkeit hinzufügen zu müssen.
Adeady
4
Dies ist die richtige Lösung. Es ist nicht erforderlich, den eckigen $ anchorScroll-Dienst einzubeziehen. Siehe Dokumentation für ein Tag: https://developer.mozilla.org/en/docs/Web/HTML/Element/a
Yiling
41
<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="faq-3">Question 3</h3>
lincolnge
quelle
Genial! Bei weitem die einfachste Lösung, aber eine Idee, wie man auf einer separaten Seite auf einen Anker verlinkt? (dh / products # books)
8bithero
Ich denke, es ist das gleiche wie die Lösung (/ products
##
1
Nach meiner Erfahrung funktioniert href = "##" nur, wenn $ anchorScroll injiziert wird.
Brian Park
9
Dies scheint relativ einfach, aber es funktioniert nicht :-(
Brykneval
4
Ich habe target = "_ self" hinzugefügt und es hat wie ein Zauber für alle Arten der Navigation innerhalb einer Seite funktioniert (Schieberegler lesen, zu verschiedenen Abschnitten gehen und so weiter). Vielen Dank, dass Sie diesen großartigen und einfachsten Trick geteilt haben.
Kumar Nitesh
19

Wenn Sie die Route immer kennen, können Sie den Anker einfach wie folgt anhängen:

href="#/route#anchorID

Wo routeist die aktuelle Winkelroute und anchorIDstimmt mit einer <a id="anchorID">irgendwo auf der Seite überein

cab1113
quelle
1
Dies löst eine normale AngularJS-Routenänderung aus und wird daher nicht empfohlen. In meinem Fall war es sehr visuell, da die YouTube-Videos auf der FAQ / Hilfeseite neu geladen wurden.
Robin Andersson
9
@ RobinWassén-Andersson Wenn Sie reloadOnSearch: falsein Ihrer Routenkonfiguration für diese Route angeben, löst Angular keine Routenänderung aus und blättert nur zur ID. In Kombination mit der im aTag angegebenen vollständigen Route würde ich sagen, dass dies die einfachste und einfachste Lösung ist.
Elise
Vielen Dank. Das hat mir geholfen. Ich verwende keine benutzerdefinierten Routen in meiner App, daher hat es großartig funktioniert, einen href = "# / # Ankernamen" zu erstellen!
Jordanien
14

$anchorScroll funktioniert dafür, aber es gibt eine viel bessere Möglichkeit, es in neueren Versionen von Angular zu verwenden.

Akzeptiert jetzt $anchorScrollden Hash als optionales Argument, sodass Sie ihn überhaupt nicht ändern müssen $location.hash. ( 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 $anchorScrollsie 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
Vielen Dank. Wie würden Sie Ihre Strategie für einen Hash-Link in Kombination mit einer Routenänderung umsetzen? Beispiel: Klicken Sie auf dieses Navigationselement, um eine andere Ansicht zu öffnen und zu einer bestimmten idAnsicht in dieser Ansicht zu scrollen.
Kyle Vassella
Sry to pester..Wenn Sie eine Chance bekommen, können Sie meiner Stack-Frage einen Blick geben? Ich habe das Gefühl, Ihre Antwort hier hat mich so nahe gebracht, aber ich kann sie einfach nicht implementieren: stackoverflow.com/questions/41494330/… . Ich benutze auch ngRouteund die neuere Version von Angular.
Kyle Vassella
Es tut mir leid, dass ich diesen speziellen Fall nicht ausprobiert habe ... aber haben Sie sich $ location.search () oder $ routeParams angesehen ? Möglicherweise können Sie bei der Initialisierung Ihres Controllers den einen oder anderen verwenden. Wenn sich Ihr scrollTo-Suchparameter in der URL befindet, kann der Controller $ anchorScroll wie oben verwenden, um die Seite zu scrollen.
Rebecca
2
Durch die direkte Übergabe der ID an $ anchorScroll änderten sich meine Routen von / contact # contact zu just / contact. Dies sollte imho die akzeptierte Antwort sein.
RandomUs1r
12

Dies war meine Lösung mit einer Direktive, die eher eckig erscheint, weil wir es mit dem DOM zu tun haben:

Plnkr hier drüben

Github

CODE

angular.module('app', [])
.directive('scrollTo', function ($location, $anchorScroll) {
  return function(scope, element, attrs) {

    element.bind('click', function(event) {
        event.stopPropagation();
        var off = scope.$on('$locationChangeStart', function(ev) {
            off();
            ev.preventDefault();
        });
        var location = attrs.scrollTo;
        $location.hash(location);
        $anchorScroll();
    });

  };
});

HTML

<ul>
  <li><a href="" scroll-to="section1">Section 1</a></li>
  <li><a href="" scroll-to="section2">Section 2</a></li>
</ul>

<h1 id="section1">Hi, I'm section 1</h1>
<p>
Zombie ipsum reversus ab viral inferno, nam rick grimes malum cerebro. De carne lumbering animata corpora quaeritis. 
 Summus brains sit​​, morbo vel maleficia? De apocalypsi gorger omero undead survivor dictum mauris. 
Hi mindless mortuis soulless creaturas, imo evil stalking monstra adventus resi dentevil vultus comedat cerebella viventium. 
Nescio brains an Undead zombies. Sicut malus putrid voodoo horror. Nigh tofth eliv ingdead.
</p>

<h1 id="section2">I'm totally section 2</h1>
<p>
Zombie ipsum reversus ab viral inferno, nam rick grimes malum cerebro. De carne lumbering animata corpora quaeritis. 
 Summus brains sit​​, morbo vel maleficia? De apocalypsi gorger omero undead survivor dictum mauris. 
Hi mindless mortuis soulless creaturas, imo evil stalking monstra adventus resi dentevil vultus comedat cerebella viventium. 
Nescio brains an Undead zombies. Sicut malus putrid voodoo horror. Nigh tofth eliv ingdead.
</p>

Ich habe den Dienst $ anchorScroll verwendet. Um der mit dem Hash-Wechsel einhergehenden Seitenaktualisierung entgegenzuwirken, habe ich das locationChangeStart-Ereignis abgebrochen. Dies funktionierte für mich, weil ich eine Hilfeseite an einen ng-Schalter angeschlossen hatte und die Aktualisierungen die App im Wesentlichen beschädigen würden.

KhalilRavanna
quelle
Ich mag Ihre Richtlinienlösung. Wie würden Sie es jedoch tun, wenn Sie eine andere Seite laden und gleichzeitig zum Ankerplatz scrollen möchten? Ohne anglejs wäre es normalerweise href = "location # hash". Ihre Anweisung verhindert jedoch das erneute Laden der Seite.
CMCDragonkai
@CMCDragonkai mit meiner Direktive bin ich mir nicht sicher, da ich den Aufruf von $ anchorScroll verwende, der anscheinend nur das Scrollen zu einem Element auf der Seite behandelt. Möglicherweise müssen Sie sich mit $ location oder $ window herumschlagen , um etwas zu erhalten, das einen Seitenwechsel beinhaltet.
KhalilRavanna
2
Sie müssen die Meldung vom locationChangeStart-Ereignis entfernen: var off = scope. $ On ('$ locationChangeStart', Funktion (ev) {off (); ev.preventDefault ();});
Guter Fang @EugeneTskhovrebov, ich habe das der Antwort in einer Bearbeitung hinzugefügt.
KhalilRavanna
5

Versuchen Sie, ein Hash-Präfix für Winkelrouten festzulegen $locationProvider.hashPrefix('!')

Vollständiges Beispiel:

angular.module('app', [])
  .config(['$routeProvider', '$locationProvider', 
    function($routeProvider, $locationProvider){
      $routeProvider.when( ... );
      $locationProvider.hashPrefix('!');
    }
  ])
Maxim Grach
quelle
Dies hat keinen Einfluss auf das Ergebnis. Es wäre aber süß.
Rasmus
2
Bist du sicher. Warum funktioniert das nicht? Wenn das Hash-Präfix! Ist, sollte das Hash-Routing die Seite #! Sein. Daher sollte AngularJS erkennen, wenn es sich nur um ein #hash handelt, den Bildlauf automatisch verankern und sowohl für URLs im HTML5-Modus als auch für URLs im Hash-Modus funktionieren.
CMCDragonkai
5

Ich habe dies in der Routenlogik für meine App umgangen.

function config($routeProvider) {
  $routeProvider
    .when('/', {
      templateUrl: '/partials/search.html',
      controller: 'ctrlMain'
    })
    .otherwise({
      // Angular interferes with anchor links, so this function preserves the
      // requested hash while still invoking the default route.
      redirectTo: function() {
        // Strips the leading '#/' from the current hash value.
        var hash = '#' + window.location.hash.replace(/^#\//g, '');
        window.location.hash = hash;
        return '/' + hash;
      }
    });
}
Nicksanta
quelle
1
Dies funktioniert nicht: Fehler: [$ injor: modulerr] Fehler beim Instanziieren des Modulwinkels aufgrund von: Fehler: ungültiger 'Handler' in when ()
geoidesic
5

Dies ist ein alter Beitrag, aber ich habe lange nach verschiedenen Lösungen gesucht, deshalb wollte ich eine einfachere teilen. Hinzufügen nur target="_self"auf die<a> Tag hat es für mich behoben. Der Link funktioniert und bringt mich zum richtigen Ort auf der Seite.

Angular fügt dem # in der URL jedoch immer noch eine gewisse Verrücktheit hinzu, sodass Sie möglicherweise Probleme haben, wenn Sie die Zurück-Schaltfläche für die Navigation und dergleichen verwenden, nachdem Sie diese Methode verwendet haben.

Benjamin
quelle
4

Dies mag ein neues Attribut für ngView sein, aber ich habe es geschafft, Anker-Hash-Links zu verwenden, um mit angular-routedem ngView autoscrollAttribut und 'Doppel-Hashes' zu arbeiten.

ngView (siehe Autoscroll)

(Der folgende Code wurde mit Winkelriemen verwendet)

<!-- 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>
Michael
quelle
3

Ich könnte das so machen:

<li>
<a href="#/#about">About</a>
</li>
Niru
quelle
2

Hier ist eine Art schmutzige Problemumgehung, indem Sie eine benutzerdefinierte Direktive erstellen, die zu einem bestimmten Element scrollt (mit fest codierter "FAQ").

app.directive('h3', function($routeParams) {
  return {
    restrict: 'E',
    link: function(scope, element, attrs){        
        if ('faq'+$routeParams.v == attrs.id) {
          setTimeout(function() {
             window.scrollTo(0, element[0].offsetTop);
          },1);        
        }
    }
  };
});

http://plnkr.co/edit/Po37JFeP5IsNoz5ZycFs?p=preview

Valentyn Shybanov
quelle
Das funktioniert zwar, ist aber, wie Sie sagten, schmutzig. Sehr dreckig. Mal sehen, ob jemand anderes eine schönere Lösung finden kann, oder ich muss mich dafür entscheiden.
Rasmus
Angular verfügt bereits über eine integrierte ScrollTo-Funktionalität $anchorScroll, siehe meine Antwort.
Ben Lesh
Der Plunker wurde so geändert, dass er weniger schmutzig ist: Er verwendet $ location.path (), sodass die Quelle keine fest codierte "FAQ" enthält. Und auch versucht, $ anchorScroll zu verwenden, aber scheint aufgrund des Routings funktioniert es nicht ...
Valentyn Shybanov
2
<a href="/#/#faq-1">Question 1</a>
<a href="/#/#faq-2">Question 2</a>
<a href="/#/#faq-3">Question 3</a>
felipe_dmz
quelle
2

Wenn Sie nicht verwenden möchten, finden Sie ng-clickhier eine alternative Lösung. Es verwendet a filter, um die richtige URL basierend auf dem aktuellen Status zu generieren. In meinem Beispiel wird ui.router verwendet .

Der Vorteil ist, dass der Benutzer sieht, wo der Link schwebt.

<a href="{{ 'my-element-id' | anchor }}">My element</a>

Der Filter:

.filter('anchor', ['$state', function($state) {
    return function(id) {
        return '/#' + $state.current.url + '#' + id;
    };
}])
Reimund
quelle
2

Meine Lösung mit ng-route war diese einfache Anweisung:

   app.directive('scrollto',
       function ($anchorScroll,$location) {
            return {
                link: function (scope, element, attrs) {
                    element.click(function (e) {
                        e.preventDefault();
                        $location.hash(attrs["scrollto"]);
                        $anchorScroll();
                    });
                }
            };
    })

Das HTML sieht aus wie:

<a href="" scrollTo="yourid">link</a>
MrFlo
quelle
Müssten Sie das Attribut nicht wie angeben scroll-to="yourid"und die Direktive benennen scrollTo(und auf das Attribut zugreifen wie attrs["scrollTo"]? Außerdem muss der Handler ohne explizite jQuery-Einbeziehung gebunden sein element.on('click', function (e) {..}).
Theodros Zelleke
1

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
1

Ich habe versucht, meine Angular-App zu einem Anker-Opon-Ladevorgang zu scrollen, und bin auf die URL-Umschreibregeln von $ routeProvider gestoßen.

Nach langen Experimenten habe ich mich dazu entschlossen:

  1. Registrieren Sie einen event.onload-Ereignishandler im Abschnitt .run () des Angular-App-Moduls.
  2. Finden Sie im Handler heraus, was das Original-Ankertag haben soll, indem Sie einige Zeichenfolgenoperationen ausführen.
  3. überschreiben Sie location.hash mit dem abgespeckten Ankertag (wodurch $ routeProvider es sofort wieder mit der Regel "# /" überschreibt. Aber das ist in Ordnung, da Angular jetzt mit dem synchronisiert ist, was in URL 4 vor sich geht) $ anchorScroll ().

angular.module("bla",[]).}])
.run(function($location, $anchorScroll){
         $(document).ready(function() {
	 if(location.hash && location.hash.length>=1)    		{
			var path = location.hash;
			var potentialAnchor = path.substring(path.lastIndexOf("/")+1);
			if ($("#" + potentialAnchor).length > 0) {   // make sure this hashtag exists in the doc.                          
			    location.hash = potentialAnchor;
			    $anchorScroll();
			}
		}	 
 });

Stoyan Kenderov
quelle
1

Ich bin nicht 100% sicher, ob dies die ganze Zeit funktioniert, aber in meiner Anwendung gibt mir dies das erwartete Verhalten.

Nehmen wir an, Sie befinden sich auf der Seite ÜBER und haben die folgende Route:

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

Nun, in Ihnen 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>

Abschließend

Das Einfügen des Seitennamens vor dem Anker hat den Trick für mich getan. Lass mich deine Gedanken wissen.

Nachteil

Dadurch wird die Seite erneut gerendert und anschließend zum Anker gescrollt.

AKTUALISIEREN

Ein besserer Weg ist, Folgendes hinzuzufügen:

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

Holen Sie sich Ihre Bildlauffunktion einfach. Als zusätzliche Funktion wird auch das animierte / reibungslose Scrollen unterstützt . Details zur Angular Scroll- Bibliothek:

Github - https://github.com/oblador/angular-scroll

Laube :bower install --save angular-scroll

npm :npm install --save angular-scroll

Minfied Version - nur 9kb

Reibungsloses Scrollen (animiertes Scrollen) - ja

Scroll Spy - ja

Dokumentation - ausgezeichnet

Demo - http://oblador.github.io/angular-scroll/

Hoffe das hilft.

Akash
quelle
1

Basierend auf @Stoyan habe ich die folgende Lösung gefunden:

app.run(function($location, $anchorScroll){
    var uri = window.location.href;

    if(uri.length >= 4){

        var parts = uri.split('#!#');
        if(parts.length > 1){
            var anchor = parts[parts.length -1];
            $location.hash(anchor);
            $anchorScroll();
        }
    }
});
ThatMSG
quelle
0

Beim Ändern der Route wird zum oberen Rand der Seite gescrollt.

 $scope.$on('$routeChangeSuccess', function () {
      window.scrollTo(0, 0);
  });

Setzen Sie diesen Code auf Ihren Controller.

Praveen MP
quelle
0

In meinen Gedanken hatte @slugslog es, aber ich würde eines ändern. Ich würde stattdessen Ersetzen verwenden, damit Sie es nicht zurücksetzen müssen.

$scope.scrollTo = function(id) {
    var old = $location.hash();
    $location.hash(id).replace();
    $anchorScroll();
};

Docs Suche nach "Methode ersetzen"

Jackie
quelle
0

Keine der oben genannten Lösungen funktioniert für mich, aber ich habe es gerade versucht, und es hat funktioniert.

<a href="#/#faq-1">Question 1</a>

Daher wurde mir klar, dass ich die Seite benachrichtigen muss, um mit der Indexseite zu beginnen und dann den herkömmlichen Anker zu verwenden.

Windmaomao
quelle
0

Manchmal in der AngularJS-Anwendung funktioniert die Hash-Navigation nicht und Bootstrap-JQuery-Javascript-Bibliotheken verwenden diese Art der Navigation in großem Umfang, damit sie target="_self"zum Ankertag hinzugefügt werden kann . z.B<a data-toggle="tab" href="#id_of_div_to_navigate" target="_self">

Kulbhushan Chaskar
quelle
0

Ich verwende AngularJS 1.3.15 und muss anscheinend nichts Besonderes tun.

https://code.angularjs.org/1.3.15/docs/api/ng/provider/ $ anchorScrollProvider

Also funktioniert folgendes für mich in meinem HTML:

<ul>
  <li ng-repeat="page in pages"><a ng-href="#{{'id-'+id}}">{{id}}</a>
  </li>
</ul>
<div ng-attr-id="{{'id-'+id}}" </div>

Ich musste überhaupt keine Änderungen an meinem Controller oder JavaScript vornehmen.

Digant C Kasundra
quelle