正しく動作するように簡単なナビゲーションを取得しようとしています。横に浮いています。ユーザーがリンクをクリックすると、ページ上のそのIDに移動します。私はこれに従っています Treehouseからのガイド 。これは私がスクロールするためのものです:
$("#quickNav a").click(function(){
var quickNavId = $(this).attr("href");
$("html, body").animate({scrollTop: $(location).offset().top}, "slow");
return false;
});
最初に</body>
の前に配置しました。しかし、私はquickNavがコンパイルされる前に発火していた競合状態に陥っているようです(ng-hide
が配置されていますが、それが原因かどうかはわかりませんが、DOM内にあります)。
そのコードブロックをコンソールで実行すると、スクロールは期待どおりに機能します。
これをコントローラーに移動する方が効果的であると考えました-または、おそらくディレクティブ内で移動します。しかし、私はそれを達成する運がありません。 このコードブロックをAngularJSで動作させるにはどうすればよいですか?
次に、クリック時に要素にスクロールする単純なディレクティブを示します。
myApp.directive('scrollOnClick', function() {
return {
restrict: 'A',
link: function(scope, $Elm) {
$Elm.on('click', function() {
$("body").animate({scrollTop: $Elm.offset().top}, "slow");
});
}
}
});
デモ: http://plnkr.co/edit/yz1EHB8ad3C59N6PzdCD?p=preview
ディレクティブの作成については、#10「最初のディレクティブ」から始まる http://egghead.io のビデオをご覧ください。
edit:hrefで指定された特定の要素までスクロールするには、attrs.href
をチェックするだけです。
myApp.directive('scrollOnClick', function() {
return {
restrict: 'A',
link: function(scope, $Elm, attrs) {
var idToScroll = attrs.href;
$Elm.on('click', function() {
var $target;
if (idToScroll) {
$target = $(idToScroll);
} else {
$target = $Elm;
}
$("body").animate({scrollTop: $target.offset().top}, "slow");
});
}
}
});
その後、次のように使用できます:<div scroll-on-click></div>
クリックした要素までスクロールします。または、<a scroll-on-click href="#element-id"></div>
を使用して、IDを持つ要素にスクロールします。
これは、使用したい場合に適したディレクティブです。
ページ内の任意の要素までスクロールできます。
.directive('scrollToItem', function() {
return {
restrict: 'A',
scope: {
scrollTo: "@"
},
link: function(scope, $Elm,attr) {
$Elm.on('click', function() {
$('html,body').animate({scrollTop: $(scope.scrollTo).offset().top }, "slow");
});
}
}})
使用法(たとえば、div 'back-to-top'をクリックするとid scroll-topにスクロールします):
<a id="top-scroll" name="top"></a>
<div class="back-to-top" scroll-to-item scroll-to="#top-scroll">
また、chrome、firefox、safari、およびhtml [body要素のIE causeによってサポートされています。
スクロールコンテナー内の特定の要素にアニメーション化するため(固定DIV)
/*
@param Container(DIV) that needs to be scrolled, ID or Div of the anchor element that should be scrolled to
Scrolls to a specific element in the div container
*/
this.scrollTo = function(container, anchor) {
var element = angular.element(anchor);
angular.element(container).animate({scrollTop: element.offset().top}, "slow");
}
$ anchorScrollを使用したangularソリューション http://www.benlesh.com/2013/02/angular-js-scrolling-to-element-by-id.html :
app.controller('MainCtrl', function($scope, $location, $anchorScroll) {
var i = 1;
$scope.items = [{ id: 1, name: 'Item 1' }];
$scope.addItem = function (){
i++;
//add the item.
$scope.items.Push({ id: i, name: 'Item ' + i});
//now scroll to it.
$location.hash('item' + i);
$anchorScroll();
};
});
そしてここにプランクがあります: http://plnkr.co/edit/xi2r8wP6ZhQpmJrBj1jM?p=preview
そして、もしあなたが純粋なjavascriptソリューションを気にかけているなら、ここに一つあります:
親コンテナIDとターゲットスクロールIDを使用して、コードでrunScrollを呼び出します。
function runScroll(parentDivId,targetID) {
var longdiv;
longdiv = document.querySelector("#" + parentDivId);
var div3pos = document.getElementById(targetID).offsetTop;
scrollTo(longdiv, div3pos, 600);
}
function scrollTo(element, to, duration) {
if (duration < 0) return;
var difference = to - element.scrollTop;
var perTick = difference / duration * 10;
setTimeout(function () {
element.scrollTop = element.scrollTop + perTick;
if (element.scrollTop == to) return;
scrollTo(element, to, duration - 10);
}, 10);
}
Andrew joslinの回答を使用しました。これはうまく機能しますが、angularルートの変更をトリガーし、私にとってびくびくしたスクロールを作成しました。ルート変更のトリガーを回避したい場合は、
myApp.directive('scrollOnClick', function() {
return {
restrict: 'A',
link: function(scope, $Elm, attrs) {
var idToScroll = attrs.href;
$Elm.on('click', function(event) {
event.preventDefault();
var $target;
if (idToScroll) {
$target = $(idToScroll);
} else {
$target = $Elm;
}
$("body").animate({scrollTop: $target.offset().top}, "slow");
return false;
});
}
}
});
例についてAndyに感謝します。これは非常に役に立ちました。単一ページのスクロールを開発しており、ハッシュバンURLの使用時にAngularを更新したくないため、少し異なる戦略の実装を終了しました。また、ブラウザの戻る/進むアクションを保持したいです。
ディレクティブとハッシュを使用する代わりに、$ location.searchで$ scope。$ watchを使用し、そこからターゲットを取得しています。これにより、きれいなアンカータグが得られます
<a ng-href="#/?scroll=myElement">My element</a>
ウォッチコードをapp.jsのモジュール宣言に次のようにチェーンしました。
.run(function($location, $rootScope) {
$rootScope.$watch(function() { return $location.search() }, function(search) {
var scrollPos = 0;
if (search.hasOwnProperty('scroll')) {
var $target = $('#' + search.scroll);
scrollPos = $target.offset().top;
}
$("body,html").animate({scrollTop: scrollPos}, "slow");
});
})
上記のコードの注意点は、別のルートから直接URLでアクセスすると、jQueryの$ target.offset()呼び出しに間に合うようにDOMがロードされない可能性があることです。解決策は、このコードを$ viewContentLoadedウォッチャー内にネストすることです。最終的なコードは次のようになります。
.run(function($location, $rootScope) {
$rootScope.$on('$viewContentLoaded', function() {
$rootScope.$watch(function() { return $location.search() }, function(search) {
var scrollPos = 0
if (search.hasOwnProperty('scroll')) {
var $target = $('#' + search.scroll);
var scrollPos = $target.offset().top;
}
$("body,html").animate({scrollTop: scrollPos}, "slow");
});
});
})
ChromeおよびFFでテスト済み
angular-scroll についてはどうですか。アクティブに維持されており、jQueryに依存していません。
別の提案。セレクター付きの1つのディレクティブ。
HTML:
<button type="button" scroll-to="#catalogSection">Scroll To</button>
角度:
app.directive('scrollTo', function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
element.on('click', function () {
var target = $(attrs.scrollTo);
if (target.length > 0) {
$('html, body').animate({
scrollTop: target.offset().top
});
}
});
}
}
});
また注意してください $ anchorScroll
非常に明確な答え、ちょうどANGULARJSを使用して、JQUERYは依存しません
htmlの一番下の<back-top>some text</back-top>
のどこかに
hTMLの最上部のどこかに<div id="top"></div>
あなたのjsで:
/**
* @ngdoc directive
* @name APP.directive:backTop
<pre>
<back-top></back-top>
</pre>
*/
angular
.module('APP')
.directive('backTop', ['$location', '$anchorScroll' ,function($location, $anchorScroll) {
return {
restrict: 'E',
replace: true,
transclude: true,
template: '<span class=\'btn btn-mute pull-right\'><i class=\'glyphicon glyphicon-chevron-up\'></i><ng-transclude></ng-transclude></span>',
scope: {
},
link: function(scope, element) {
element.on('click', function(event) {
$anchorScroll(['top']);
});
}
};
}]);