1. ホーム
  2. ジャバスクリプト

[解決済み】AngularJSでアンカーハッシュのリンクを処理する方法

2022-03-27 08:49:06

質問

でのアンカーハッシュリンクをうまく処理する方法をご存知の方はいらっしゃいますか? AngularJS ?

私は、単純な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>

上記のリンクのいずれかをクリックすると、AngularJSがインターセプトして、まったく別のページ(私の場合は、リンクに一致するルートがないため404ページ)にルーティングします。

最初に考えたのは、"にマッチするルートを作成することでした。 /faq/:章 をチェックし、対応するコントローラで $routeParams.chapter の後、マッチする要素までjQueryでスクロールダウンします。

でも、AngularJSはまた私をバカにして、とにかくページの一番上までスクロールさせるんです。

そこで、どなたか過去に同じようなことをされた方で、良い解決策をご存知の方はいらっしゃいませんか?

編集:html5Modeに切り替えると問題が解決するはずですが、いずれにせよIE8+をサポートしなければならないので、それが受け入れられる解決策であるかどうか心配です :/。

解決方法は?

あなたが探しているのは $anchorScroll() .

これが(しょぼい)ドキュメントです。

そして、こちらがそのソースです。

基本的には、これを注入してコントローラで呼び出すだけで、以下の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>

以下は、デモ用のプランカーです。

EDIT: ルーティングで使用する場合

通常通りangularルーティングを設定し、以下のコードを追加するだけです。

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

と入力すると、リンクは次のようになります。

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

以下は ルーティングと $anchorScroll を使ったスクロールのデモをするプランカー

そして、さらにシンプルに

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

と入力すると、リンクは次のようになります。

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