The Round

合同会社ナイツオの開発ブログ

静岡でGo言語やりたい人!!→こちら

ionicでAngularJSの$anchorScrollを使ってハマった

ionicでAngularJSの$anchorScrollを使ってハマった

だいぶお久しぶりになりますマツウラです。
今回はionic frameworkでAngularJSの$anchorScrollが期待通りに動作しなかったことについてです。

まず結論から書いておきます。

結論:$ionicScrollDelegateを使う

AngularJSの$anchorScrollではなく、ionicの$ionicScrollDelegate serviceを使ってください。

実際にハマった経緯について書いておきます。

$anchorScrollを使う

WebViewを使ったモバイル・アプリの開発中に、HTML中の指定要素までスクロールしたい場面がありました。
HTMLは次のとおりです。

<ion-content ng-controller="ItemsCtrl">
  <div class="card" ng-repeat="item in items">
    <div id="anchor{{$index}}" class="item item-text-wrap">
      <!--content-->
    </div>
  </div>
</ion-content>

そして、AngularJSの$locationと$anchorScrollを使ったスクロールを実装しました。

Pure AngularJSの場合

AngularJSの機能のみでスクロールを実装する場合、次のようなコードを考えました。
実際に指定のIDにスクロールする際に下記scrollToを呼び出すことになります。

$scope.scrollTo = function(id) {
    if($location.hash() !== id) {
        $location.hash(id);
    }else {
        $anchorScroll();
    }
};

しかし、上記コードでは何の動作もしませんでした。
いったい何がいけなかったのでしょう?

原因

この問題はionicの公式フォーラムで判りました。
Hashbang scroll - can’t scroll up to top of content manually

フォーラムの3番目のポストではionicの共同制作者の方が投稿してくれています。

まずionicではカスタムスクロール機構を採用しているため、$anchorScrollは動作しないとのことでした。
代わりに$ionicScrollDelegateを使ってくれという話でした。

解決

実際に$ionicScrollDelegateを使ってコードを書いてみました。
jsコードは次のようになります。

$scope.scrollTo = function(id) {
    if($location.hash() !== id) {
      $location.hash(id);
    }
    $ionicScrollDelegate.anchorScroll(true);
}

これで無事に指定IDまでスクロールさせることが出来るようになりました!


ionicはCSS frameworkとJavaScript UIライブラリの両方の機能を持ち、AngularJSの拡張機能として開発されています。
そのためAngularJSとの相性は非常に良いのが特徴です。

ただ、今回のようにionic側の実装に影響を受け、代わりのAPIが提供されている場合があります。
何らかの機能を実装する場合は、一度関連しそうな項目がないか公式Docを参照してみると良いかもしれません。