323 votes

Comment gérer la liaison de hachage d'ancrage dans AngularJS

Ne l'un de vous sais comment faire pour bien gérer l'ancre de hachage de liaison dans les AngularJS?

J'ai le balisage suivant pour une simple page de FAQ

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

Lorsque vous cliquez sur un des liens ci-dessus, AngularJS intercepte et les itinéraires de moi une autre page (dans mon cas, une page 404 comme il n'y a pas de routes à la correspondance de la des liens.)

Ma première pensée a été de créer une correspondance de route "/faq/:chapitre" et dans le contrôleur correspondant case $routeParams.chapitre après un élément correspondant et ensuite utiliser jQuery pour faire défiler vers le bas pour elle. Mais alors, AngularJS chie sur moi à nouveau et défile vers le haut de la page de toute façon.

Donc, si quelqu'un ici fait quelque chose de similaire dans le passé et qui sait, une bonne solution?

Edit: Mise à html5Mode devrait résoudre mes problèmes, mais nous avons un peu à l'appui de IE8+ de toute façon donc j'ai peur que cela n'est pas une solution retenue :/

379voto

Ben Lesh Points 39290

Vous êtes à la recherche pour $anchorScroll().

Voici l' (de merde) de la documentation.

Et voici le code source.

Fondamentalement, il suffit d'injecter de l'il et de l'appeler dans votre contrôleur, et il vous en faites défiler jusqu'à un élément avec l'id trouvé en $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>

Voici une plunker à démontrer

EDIT: pour l'utiliser avec de routage

Configurer votre angulaire de routage comme d'habitude, puis il suffit d'ajouter le code suivant.

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();  
  });
});

et votre lien devrait ressembler à ceci:

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

Voici une Plunker démonstration de défilement avec le service routage et $anchorScroll

171voto

slugslog Points 581

Dans mon cas, j'ai remarqué que la logique de routage entrait en action si je modifiais le hachage de localisation. le tour suivant a fonctionné ..

 $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);
};
 

41voto

lincoln Points 146
<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>

20voto

cab1113 Points 81

Si vous connaissez toujours l'itinéraire, vous pouvez simplement ajouter l'ancre comme ceci:

 href="#/route#anchorID
 

route est la route angulaire actuelle et anchorID correspond à un <a id="anchorID"> quelque part sur la page

13voto

KhalilRavanna Points 821

C'était ma solution à l'aide d'une directive qui semble plus Angulaires-y parce que nous traitons avec les DOM:

Plnkr ici

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>

J'ai utilisé la somme de anchorScroll service. Pour contrer la page d'actualisation qui va de pair avec le hash de changer, je suis allé de l'avant et l'annulation de la locationChangeStart événement. Cela a fonctionné pour moi parce que j'ai eu une page d'aide accroché à une ng-commutateur et le rafraîchit serait esentially pause de l'application.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X