[英]Changing route doesn't scroll to top in the new page
当路线改变时,我发现了一些不受欢迎的行为,至少对我而言。 在教程http://angular.github.io/angular-phonecat/step-11/app/#/phones的第11步中,您可以看到手机列表。 如果您滚动到底部并单击最新的一个,您可以看到滚动不在顶部,而是在中间。
我也在我的一个应用程序中找到了这个,我想知道如何让它滚动到顶部。 我可以手工做,但我认为应该有其他优雅的方式来做这个,我不知道。
那么,当路线改变时,是否有一种优雅的方式滚动到顶部?
问题是ngView在加载新视图时会保留滚动位置。 您可以指示$anchorScroll
“在视图更新后滚动视口”( 文档有点模糊,但滚动到这里意味着滚动到新视图的顶部 )。
解决方案是将autoscroll autoscroll="true"
添加到ngView元素:
<div class="ng-view" autoscroll="true"></div>
只需将此代码运行即可
$rootScope.$on("$routeChangeSuccess", function (event, currentRoute, previousRoute) {
window.scrollTo(0, 0);
});
这段代码对我来说非常有用..我希望它对你来说也很有用..你所要做的只是将$ anchorScroll注入你的运行块并将监听器函数应用到rootScope,就像我在下面的例子中所做的那样。
angular.module('myAngularApp')
.run(function($rootScope, Auth, $state, $anchorScroll){
$rootScope.$on("$locationChangeSuccess", function(){
$anchorScroll();
});
这是Angularjs模块的调用顺序:
app.config()
app.run()
directive's compile functions (if they are found in the dom)
app.controller()
directive's link functions (again, if found)
RUN BLOCK在创建注入器后执行并用于kickstart应用程序..这意味着当您重定向到新的路由视图时,运行块中的侦听器调用
$ anchorScroll()
你现在可以看到滚动从新的路由视图开始到顶部:)
尝试ui-view autoscroll=true
, $stateChangeStart
, $locationChangeStart
, $uiViewScrollProvider.useAnchorScroll()
, $provide('$uiViewScroll', ...)
和其他许多其他组合的一两个小时后,我无法'滚动到新页面滚动按预期工作。
这最终对我有用。 它捕获pushState和replaceState,仅在导航新页面时更新滚动位置(后退/前进按钮保留其滚动位置):
.run(function($anchorScroll, $window) {
// hack to scroll to top when navigating to new URLS but not back/forward
var wrap = function(method) {
var orig = $window.window.history[method];
$window.window.history[method] = function() {
var retval = orig.apply(this, Array.prototype.slice.call(arguments));
$anchorScroll();
return retval;
};
};
wrap('pushState');
wrap('replaceState');
})
这是我(看似)强大,完整和(相当)简洁的解决方案。 它使用缩小兼容样式(以及对模块的angular.module(NAME)访问)。
angular.module('yourModuleName').run(["$rootScope", "$anchorScroll" , function ($rootScope, $anchorScroll) {
$rootScope.$on("$locationChangeSuccess", function() {
$anchorScroll();
});
}]);
PS我发现autoscroll事件无论是设置为true还是false都没有影响。
使用angularjs UI路由器,我正在做的是:
.state('myState', {
url: '/myState',
templateUrl: 'app/views/myState.html',
onEnter: scrollContent
})
附:
var scrollContent = function() {
// Your favorite scroll method here
};
它永远不会在任何页面上失败,并且它不是全局的。
对于任何遇到标题中描述的问题的人(如我所做的那样),他们也在使用AngularUI路由器插件...
正如在这个问题中所提出的那样,当你改变路线时,angular-ui路由器会跳到页面底部。
无法弄清楚为什么页面在底部加载? Angular UI-Router自动滚动问题
但是,正如答案所述,您可以通过在ui-view
上说autoscroll="false"
来关闭此行为。
例如:
<div ui-view="pagecontent" autoscroll="false"></div>
<div ui-view="sidebar" autoscroll="false"></div>
http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.directive:ui-view
你可以使用这个JavaScript
$anchorScroll()
如果您使用ui-router,您可以使用(运行中)
$rootScope.$on("$stateChangeSuccess", function (event, currentState, previousState) {
$window.scrollTo(0, 0);
});
我找到了这个解决方案 如果您转到新视图,该函数将被执行。
var app = angular.module('hoofdModule', ['ngRoute']);
app.controller('indexController', function ($scope, $window) {
$scope.$on('$viewContentLoaded', function () {
$window.scrollTo(0, 0);
});
});
将autoScroll设置为true对我来说不是技巧,所以我选择了另一种解决方案。 我构建了一个服务,每次路由更改时挂钩,并使用内置的$ anchorScroll服务滚动到顶部。 适合我:-)。
服务:
(function() {
"use strict";
angular
.module("mymodule")
.factory("pageSwitch", pageSwitch);
pageSwitch.$inject = ["$rootScope", "$anchorScroll"];
function pageSwitch($rootScope, $anchorScroll) {
var registerListener = _.once(function() {
$rootScope.$on("$locationChangeSuccess", scrollToTop);
});
return {
registerListener: registerListener
};
function scrollToTop() {
$anchorScroll();
}
}
}());
注册:
angular.module("mymodule").run(["pageSwitch", function (pageSwitch) {
pageSwitch.registerListener();
}]);
派对有点晚了,但我已经尝试了所有可能的方法,没有任何正常的方法。 这是我优雅的解决方案:
我使用一个控制器来管理我的所有页面与ui-router。 它允许我将未经过身份验证或验证的用户重定向到适当的位置。 大多数人将他们的中间件放在他们的应用程序配置中,但我需要一些http请求,因此全局控制器对我来说效果更好。
我的index.html看起来像:
<main ng-controller="InitCtrl">
<nav id="top-nav"></nav>
<div ui-view></div>
</main>
我的initCtrl.js看起来像:
angular.module('MyApp').controller('InitCtrl', function($rootScope, $timeout, $anchorScroll) {
$rootScope.$on('$locationChangeStart', function(event, next, current){
// middleware
});
$rootScope.$on("$locationChangeSuccess", function(){
$timeout(function() {
$anchorScroll('top-nav');
});
});
});
我已经尝试了所有可能的选项,这种方法效果最好。
上面的所有答案都打破了预期的浏览器行为。 大多数人想要的是如果它是一个“新”页面将滚动到顶部的东西,但如果你通过后退(或前进)按钮到达那里,则返回到前一个位置。
如果你假设HTML5模式,事实证明这很容易(虽然我确信一些聪明的人可以弄清楚如何让这更优雅!):
// Called when browser back/forward used
window.onpopstate = function() {
$timeout.cancel(doc_scrolling);
};
// Called after ui-router changes state (but sadly before onpopstate)
$scope.$on('$stateChangeSuccess', function() {
doc_scrolling = $timeout( scroll_top, 50 );
// Moves entire browser window to top
scroll_top = function() {
document.body.scrollTop = document.documentElement.scrollTop = 0;
}
它的工作方式是路由器假定它将滚动到顶部,但延迟一点,以使浏览器有机会完成。 如果浏览器然后通知我们该更改是由后退/前进导航引起的,则它会取消超时,并且永远不会发生滚动。
我使用原始document
命令进行滚动,因为我想移动到窗口的整个顶部。 如果您只想滚动ui-view
,请设置autoscroll="my_var"
,您my_var
使用上述技术控制my_var
。 但我想大多数人都希望滚动整个页面,如果您要将页面作为“新”页面。
以上使用ui-router,但你可以使用ng-route代替$stateChangeSuccess
$routeChangeSuccess
$stateChangeSuccess
。
提供的答案都没有解决我的问题。 我在视图之间使用动画,滚动总是在动画之后发生。 我找到的解决方案,以便在动画之前滚动到顶部是以下指令:
yourModule.directive('scrollToTopBeforeAnimation', ['$animate', function ($animate) {
return {
restrict: 'A',
link: function ($scope, element) {
$animate.on('enter', element, function (element, phase) {
if (phase === 'start') {
window.scrollTo(0, 0);
}
})
}
};
}]);
我把它插入我的视图如下:
<div scroll-to-top-before-animation>
<div ng-view class="view-animation"></div>
</div>
简单解决方案,在启用的主路径模块中添加scrollPositionRestoration
。
像这样:
const routes: Routes = [
{
path: 'registration',
loadChildren: () => RegistrationModule
},
];
@NgModule({
imports: [
RouterModule.forRoot(routes,{scrollPositionRestoration:'enabled'})
],
exports: [
RouterModule
]
})
export class AppRoutingModule { }
试试这个http://ionicframework.com/docs/api/service/ $ ionicScrollDelegate /
它会滚动到列表顶部scrollTop()
我终于得到了我需要的东西。
我需要滚动到顶部,但想要一些转换不到
您可以在逐个路由级别上控制它。
我正在将@wkonkel的上述解决方案与一些路由声明中添加一个简单的noScroll: true
参数结合起来。 然后我在过渡中抓住了那个。
总而言之:它在新转换时浮动到页面顶部,它不会在Forward
/ Back
转换中浮动到顶部,并且它允许您在必要时覆盖此行为。
代码:(以前的解决方案加上额外的noScroll选项)
// hack to scroll to top when navigating to new URLS but not back/forward
let wrap = function(method) {
let orig = $window.window.history[method];
$window.window.history[method] = function() {
let retval = orig.apply(this, Array.prototype.slice.call(arguments));
if($state.current && $state.current.noScroll) {
return retval;
}
$anchorScroll();
return retval;
};
};
wrap('pushState');
wrap('replaceState');
把它放在app.run
块中并注入$state
... myApp.run(function($state){...})
然后,如果您不想滚动到页面顶部,请创建如下路线:
.state('someState', {
parent: 'someParent',
url: 'someUrl',
noScroll : true // Notice this parameter here!
})
这对我来说包括自动滚动
<div class="ngView" autoscroll="true" >
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.