_ui-router 0.2.8
_から_0.2.0
_にアップグレードしたばかりで、状態が変わると、スクロール位置が新しい子の対象である_ui-view
_の先頭にジャンプすることに気付きました状態。
これは問題ありませんが、2つの問題があります。
1)ページの上部と_ui-view
_の間に30pxのパディングがあり、ギャップを残してページの上部までスクロールしたい。現時点では、それは_ui-view
_の最上部に正確に移動し、見苦しくなります。これを達成するには、UIビューが存在するdivの上部(ブラウザviewport
ではない)にスクロールする方法を知る必要があるか、オーバーライドする方法を見つける必要があると思います_$uiViewScroll
_は、_ui-view
_から30pxを引いてスクロールします。
$uiViewScrollProvider.useAnchorScroll();
を試しましたが、それを行ってもまったくスクロールしません。スクロールを完全に停止する_<ui-view autoscroll="false">;
_も試しました。
2)現時点では実際にはスクロールせず、ジャンプするだけです。スクロールすることを想定していますか、それともCSSトランジションでこれを行うのは開発者次第ですか?
どんな助けも本当に感謝されます:)
別のアプローチは、デフォルトの$uiViewScroll
サービス。デフォルトの動作を効果的にオーバーライドします。
app.config(function ($provide) {
$provide.decorator('$uiViewScroll', function ($delegate) {
return function (uiViewElement) {
// var top = uiViewElement.getBoundingClientRect().top;
// window.scrollTo(0, (top - 30));
// Or some other custom behaviour...
};
});
});
ハブラスが述べたように、<ui-view>
これを適用したくない場合は、単にautoscroll="false"
。私は実際のスクロールの実装をよく見ていないので、デコレータの方法(それはたくさんの楽しみです)を代替として言及するだろうと考えました。正確なスクロール動作を解決できると確信しています。
パスが変更されるたびに、ルーターはイベントをブロードキャストします:$ stateChangeSuccessつまりURLが変更されたので、それを聞いてjqueryを使用してページの上部までスクロールします
$rootScope.$on('$stateChangeSuccess',function(){
$("html, body").animate({ scrollTop: 0 }, 200);
})
上記のコードを内部に配置します
yourAppName.run(function(){
//the above code here
})
だから私はこれと同じ問題を抱えていた。固定トップのナビゲーションバーがあります。 ui-viewにautoscroll = "true"を設定すると、スクロールバーの高さの高さを引いた上にスクロールします。
だから私は一番上のナビゲーションバーのボディにパディングを追加したスタイルを取り除きました
// fixed navigation at top
//body { padding-top: 100px; }
そして、それをUIビューに適用しました
[ui-view=main] {
padding-top: 100px;
}
Autoscroll = "true"が期待どおりに機能するようになりました。
1)autoscroll="false"
ui-viewで、$viewContentLoaded
イベント。
2)これは、アンカーに対するブラウザのデフォルトの動作です
$stateChangeSuccess
は現在のAngularJS(1.2.xとして)ではもう利用できないようです。RishulMattasの例を次のように変更しました。
app.run(function ($rootScope) {
$rootScope.$on('$viewContentLoaded',function(){
jQuery('html, body').animate({ scrollTop: 0 }, 200);
});
});
上に置く
<div id="top">.....
スクロールするコード:
$rootScope.$on('$stateChangeStart', function() {
$anchorScroll('top');
});
ナビゲーション状態が子状態の場合、上にスクロールする必要はないと思うので、これを書きました。
$rootScope.$on('$stateChangeSuccess',function(_, _, _, os){
if(!$state.includes(os) || $state.is(os))
$("html, body").animate({ scrollTop: 0 }, 200);
});
Angular + Material Designを組み合わせた場合、上にスクロールするにはこれも必要です。
app.run(function ($rootScope) {
$rootScope.$on('$viewContentLoaded', function () {
$("md-content").animate({ scrollTop: 0 }, "fast"); /* <------- Notice this line */
jQuery('html, body').animate({ scrollTop: 0 }, 200);
});
});
ほとんどの場合、ページの一番上までスクロールするだけでは十分ではありません。アンカーリンクを尊重し、場所のハッシュで指定されたロード済みコンテンツの特定の場所にスクロールすることは常に良い考えです。
この戦略を実装するために使用するコードは次のとおりです。
module.run(function (
$rootScope,
$timeout,
$location,
$uiViewScroll
) {
// Scrolling when screen changed.
$rootScope.$on('$viewContentLoaded', function () {
$timeout(performAutoScroll, 0);
});
function performAutoScroll () {
var hash = $location.hash();
var element =
findDomElement('#' + hash)
|| findDomElement('a[name="' + hash + '"]')
|| angular.element(window.document.body)
;
$uiViewScroll(element);
}
});
$viewContentLoaded
は、コンテンツがui-view
要素内にロードされたときにAngularによって生成されるイベントです。実際には、コードを移動するには、コードの実行を延期する必要がありますこの方法では、ビュー要素のコンテンツが実際にDOMツリーに配置されるため、クエリを実行できます$timeout
遅延ゼロのトリックがこの目的に使用されます。
I Routerによって提供される$uiViewScroll
サービスは、実際にスクロールを行うために使用されます。それにjQuery/jqLite要素を渡すことができ、それは上境界までスクロールします。
$location
サービスから正しいハッシュを取得し、それを使用してDOMツリー内の適切な要素を見つけています。 id
属性を持つ要素、またはname
属性を持つリンクのいずれかです。スクロールする要素が見つからない場合は、body
要素にフォールバックします(つまり、ページの上部にスクロールします)。
そして、findDomElement
は単なる構文上の砂糖です。次のように定義されました:
/**
* @param {string} selector
* @returns {jQuery|null}
*/
function findDomElement (selector) {
var result = $(selector);
return (result.length > 0 ? result : null);
}
このアプローチが理にかなっており、外部の誰かに役立つことを願っています。乾杯!
条件付きでビューでこれを行いたい場合は、次のようにコントローラービューに配置できます。
.state('exampleState', {
url: '/exampleURL',
controller: 'ExampleCtrl as examplectrl',
onEnter: function($rootScope) {
$rootScope.$on('$viewContentLoaded',function(){
jQuery('html, body').animate({ scrollTop: 0 }, 200);
});
}
}).
または、必要に応じて、state.jsファイルをよりきれいに保ち、上記のビューのコントローラーに上記を配置します。
function ExampleCtrl ($scope, $rootScope) {
$rootScope.$on('$viewContentLoaded',function(){
jQuery('html, body').animate({ scrollTop: 0 }, 200);
});
}
これが誰かを助けることを願って、私が何かを逃しているならば、私に知らせてください。私は後者を使用し、私にとっては素晴らしい作品です。