#idでhrefで指定されたアンカー要素にスクロールするようにAngularJsを設定する方法は?
問題
ハッシュ付きのアンカーリンク。href="#recommanded" は url#recommanded ではなく url#/recommanded になるため、期待どおりにスクロールしません。angularjs ライブラリがロードされていない場合、正常に動作します。ステータスバーでカーソルをリンクの上に移動すると、ブラウザーのステータスバーには、これから向かおうとしているリンクが正しく表示されますが、クリックすると変換されて正しくスクロールしません。angularのルートは使用していません。
スクロール/jsの位置操作に干渉している可能性のあるAngularJSコードのスニペット:
...
app.config([ '$httpProvider', '$compileProvider', function($httpProvider, $compileProvider) {
$compileProvider.debugInfoEnabled(false);
// Initialize get if not there
if (!$httpProvider.defaults.headers.get) {
$httpProvider.defaults.headers.get = {};
}
// Disable IE ajax request caching
$httpProvider.defaults.headers.get['If-Modified-Since'] = '0';
} ]);
...
app.directive('jumpForm', function($timeout) {
return {
restrict : 'A',
link : function(scope, elem) {
// set up event handler on the form element
elem.on('submit', function() {
$timeout(function() {
// find the first invalid element
var firstInvalid = elem[0].querySelector('.has-error');
// if we find one, set focus
if (firstInvalid) {
$('html, body').animate({
duration : 2000,
scrollTop : (firstInvalid.offsetTop + 100)
});
}
}, 200);
});
}
};
});
...
app.factory('httpResponseInterceptor', [ '$q', '$location', '$window', function($q, $location, $window) {
return {
response : function(response) {
if (response && response.data && response.data.errorCode == 'AUTHENTICATION_REQUIRED') {
var _context = $("body").attr("data-context");
var redirectUrl = _context + '/registration?msg=session_expired';
$window.location.href = redirectUrl;
return $q.reject(response);
}
return response;
}
}
} ]);
app.config([ '$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push('httpResponseInterceptor');
} ]);
ハッシュタグ付きの通話:
<a href="#recommanded"> </a>
試行錯誤
内部の回避策
アンカースクロール
AngularJS でアンカー ハッシュ リンクを処理する方法のスレッドでは、次のスニペットを挿入することをお勧めします。
app.controller('TestCtrl', function($scope, $location, $anchorScroll) {
$scope.scrollTo = function(id) {
$location.hash(id);
$anchorScroll();
}
});
そしてそれを呼び出す際に:
<a ng-click="scrollTo('recommanded')">Foo</a>
これにより、コンソールにエラーは発生しませんが、以前と同じ動作になります。URL はスクロールせずにアンカーに変換されます。また、これに ng-click 機能を持たせるという考えも好きではありません。
私のangularjsに次を追加しました:
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#recommanded">Test/Foo</a>
エラーは発生しませんでしたが、スクロールも機能しませんでした。
href で #/#recommanded を実行することをほのめかしている人もいます。target="_self" を使用します。それらのどれも私のためにうまくいきませんでした。
外部の回避策
ディレクティブ scrollTo
app.directive('scrollto',
function ($anchorScroll,$location) {
return {
link: function (scope, element, attrs) {
element.click(function (e) {
e.preventDefault();
$location.hash(attrs["scrollto"]);
$anchorScroll();
});
}
};
})
html は次のようになります。
<a href="" scrollTo="recommanded">link</a>
これは実際には機能しますが、呼び出し href="#recommended" が機能するソリューションを好むでしょう。または、少なくともスクロールをアニメーション化します。
angular-scroll の du-smooth-scroll
angularApp.js にduScrollを追加しました: var app = angular.module('app', [ ..., 'duScroll' ]);
angular-scroll.min.js ファイルが angularApp.js を含むページにエラーなく読み込まれました。<a du-smooth-scroll href="#recommended-to-you">recommanded</a>
その ID を持つ既存の divを呼び出します。しかし、それは何もしません.jsエラーはありませんが、動きません. 明示的な緩和期間などの設定を追加して duScroll モジュールを試してみましたが、エラーはありませんが機能しません。