我有一个隐藏项目列表。
我需要在单击后显示该列表并滚动到其中一个项目。
我在此处复制了代码:http://plnkr.co/edit/kp5dJZFYU3tZS6DiQUKz?p=preview
从控制台中可以看到,scrollTop()在项目可见之前被调用,因此我认为ng-show不是即时的,这种方法是错误的。
通过使用超时延迟scrollTop(),它可以正常工作,但我不想这样做。
是否有其他解决方案?
是否有其他解决方案?
在使用 ng-show
时,我没有看到其他解决方案,除了推迟对 scrollTop()
的调用。您必须等待模型中的更改反映到DOM中,以使元素变为可见。它们不会立即出现的原因是作用域生命周期。 ng-show
内部使用一个监视器,只有在调用作用域的 $digest()
函数之后执行完点击处理程序中的完整代码后才会触发。
有关作用域生命周期的更详细说明,请参见http://docs.angularjs.org/api/ng.$rootScope.Scope。
通常,使用无延迟执行的超时器应该不是问题,像这样:
setTimeout(function() {
$(window).scrollTop(50);
}, 0);
无需超时的替代解决方案:
然而,如果你想避免超时事件(其执行可能在事件队列中的其他事件之前),并确保滚动发生在单击事件处理程序内部。您可以在控制器中执行以下操作:
$scope.$watch('itemsVisible', function(newValue, oldValue) {
if (newValue === true && oldValue === false) {
$scope.$evalAsync(function() {
$(window).scrollTop(50);
});
}
});
当使用ng-show
指令注册的watch listener在同一个$digest()
周期内触发时,监听器会与ng-show
指令注册的watch listener一起被执行。传递给$evalAsync()
的函数将在Angular处理完所有的watch listener之后立即执行,所以元素已经被ng-show
指令显示出来了。
$evalAsync
的行为在新版本的Angular中已经发生了变化。 - lex82$anchorScroll
。https://docs.angularjs.org/api/ng/service/$anchorScroll
例子:
$scope.showDiv = function()
{
$scope.showDivWithObjects = true;
$location.hash('div-id-here');
$anchorScroll();
}