有angular的ui路由器滚动到顶部,而不是ui-view
我刚刚从0.2.0
升级到ui-router 0.2.8
,我注意到当状态改变时,滚动位置跳转到新状态主题的子ui-view
顶部。
这很好,但我有两个问题:
1)我有页面顶部和ui-view
之间的30px填充,我希望它滚动到页面的顶部,留下一个空白。 目前它正好到了看起来丑陋的ui-view
的顶端。 为了实现这一点,我想我需要知道如何让它滚动到$uiViewScroll
视图所在的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... }; }); });
正如Hubrus所提到的,对于任何<ui-view>
你不希望这个申请,只需添加autoscroll="false"
。 我没有看到实际的滚动实现,我只是想提出装饰的方式(它很有趣)作为替代。 我相信你可以制定出确切的滚动行为。
当path改变时,路由器广播一个事件:$ 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)我认为最简单的方式来把ui-view上的$viewContentLoaded
autoscroll="false"
,并操纵$viewContentLoaded
事件中的滚动。
2)这是浏览器在锚上的默认行为
由于$stateChangeSuccess
在当前的AngularJS(如1.2.x)中似乎不再可用,所以我将Rishul Mattas示例更改为以下适用于我的方法:
app.run(function ($rootScope) { $rootScope.$on('$viewContentLoaded',function(){ jQuery('html, body').animate({ scrollTop: 0 }, 200); }); });
放在最上面
<div id="top">.....
滚动代码:
$rootScope.$on('$stateChangeStart', function() { $anchorScroll('top'); });
如果将angular度+材质devise结合起来,则还需要滚动到顶部:
app.run(function ($rootScope) { $rootScope.$on('$viewContentLoaded', function () { $("md-content").animate({ scrollTop: 0 }, "fast"); /* <------- Notice this line */ jQuery('html, body').animate({ scrollTop: 0 }, 200); }); });
我觉得如果浏览状态是子状态,我们不需要滚动到顶部,所以我写了这个:
$rootScope.$on('$stateChangeSuccess',function(_, _, _, os){ if(!$state.includes(os) || $state.is(os)) $("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生成的事件。 实际上,我们需要推迟执行我们的代码,以便将其移至下一个摘要循环。 这样view元素的内容将被实际放置在DOM树中,所以我们可以查询它。 具有零延迟技巧的$timeout
用于此目的。
由UI Router提供的$uiViewScroll
服务实际上用于滚动。 我们可以传递一个jQuery / jqLite元素给它,它将滚动到它的顶部边框。
我们从$location
服务获取currect哈希,并使用它来查找DOM树中的正确元素。 它可以是具有id
属性的元素,也可以是具有name
属性的链接。 如果我们不能find一个元素滚动到我们回落到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); }); } }).
或者可以select哪个可以让你的state.js文件更干净地将上面的内容放在给定视图的控制器中:
function ExampleCtrl ($scope, $rootScope) { $rootScope.$on('$viewContentLoaded',function(){ jQuery('html, body').animate({ scrollTop: 0 }, 200); }); }
希望这有助于某人,请让我知道如果我失去了一些东西。 我用后者,对我很好。