防止滚动 AngularJs 上动态更新的可滚动 div
Posted
技术标签:
【中文标题】防止滚动 AngularJs 上动态更新的可滚动 div【英文标题】:Prevent scrolling of a scrollable div dynamically updated on AngularJs 【发布时间】:2016-01-06 09:05:41 【问题描述】:我有一个带有类似 powerpoint 界面的 Angular 应用程序。
左侧项目(可滚动的<div>
)是使用ui-sref
调用的控制器的一部分,幻灯片内容来自另一个(子)控制器并使用ng-show
进行更新。
如果我点击一个项目(图片左侧),幻灯片内容(右侧)会动态变化。问题是当一个项目被点击时,可滚动视图总是滚动到顶部。
我尝试了许多关于 SO 的方法,但没有任何效果:
在ui-view
上将属性autoscroll
设置为false
myModule.value('$anchorScroll', angular.noop);
myModule.run(['$anchorScroll', function($anchorScroll)
$anchorScroll = angular.noop; ]);
$anchorScrollProvider.disableAutoScrolling();
在这里编辑/所有链接标签的属性:
ui-sref="linkquestion"
ng-repeat="question in questionnaire.Question | orderBy: 'numero' | filter:statut: false"
ng-mouseenter="options = true"
ng-mouseleave="options = false"
有人有想法吗?
【问题讨论】:
我认为最简单最正确的方法是使用 UI-Router 的 Nested States & Views github.com/angular-ui/ui-router#nested-states--views 和侧边栏是一个视图,主要是第二个,区别在于ui-sref
侧边栏主循环中的元素ID
不幸的是,屏幕截图本身并不能很好地说明问题,无法提供完整的答案。请提供问题的minimal reproducible example。
你能提供小提琴吗?
拉法尔是对的。如果您正在重新加载 dom 的“幻灯片动态”部分,则单击项目后滚动不应重置。如果发生这种情况,可能另一个角度循环会出于某种内部目的而遍历项目 ui-srefs。我建议将左侧包装在另一个与角度刷新隔离的 div 中
能否请您发布完整的 锚标签?
【参考方案1】:
我不完全确定您正在尝试使用 $anchorScroll
做什么,但正如 cmets 建议的那样,您可能想要使用 ui-router
和 ui-view
而不是 ng-show
。此外,如果没有示例代码或 有点 工作示例作为基线,要完全剖析您的示例并引导您朝着正确的方向前进是有点困难的。但是,从你的图表中,我至少知道你在追求什么——所以我做了一个最好的猜测。
我鼓励您放弃使用 ng-show
并重新考虑您的标记以支持使用 ui-view
。我制作了一个与您的概念类似的示例,我可以动态更改状态并显示内容无需滚动跳转。观察以下完整的工作示例...
<section class="container">
<aside>
<a ng-repeat="n in nav" ui-sref=" n.state ">state: n.state </a>
</aside>
<div ui-view></div>
</section>
angular.module('app', ['ui.router'])
.config(['$stateProvider', function($stateProvider)
$stateProvider
.state('a', template: '<span>a</span>' )
.state('b', template: '<span>b</span>' )
.state('c', template: '<span>c</span>' )
.state('d', template: '<span>d</span>' )
.state('e', template: '<span>e</span>' )
.state('f', template: '<span>f</span>' )
.state('g', template: '<span>g</span>' )
.state('h', template: '<span>h</span>' )
.state('i', template: '<span>i</span>' )
.state('j', template: '<span>j</span>' )
.state('k', template: '<span>k</span>' )
.state('l', template: '<span>k</span>' );
])
.controller('ctrl', ['$scope', function($scope)
$scope.nav = [
'state': 'a' , 'state': 'b' , 'state': 'c' ,
'state': 'd' , 'state': 'e' , 'state': 'f' ,
'state': 'g' , 'state': 'h' , 'state': 'i' ,
'state': 'j' , 'state': 'k' , 'state': 'l'
];
]);
请原谅我的状态和内容太简单了——这只是为了演示。但是,您将能够看到工作示例中的行为,并有望将此基础塑造到您的工作副本中。
JSFiddle Link - 工作演示
与往常一样,请务必查看ui-router docs 了解更多信息。
根据您的评论,这可能是一种更动态的方式。在此,我只是定义一个参数化并订阅$stateChangeSuccess
事件的状态——让我有机会根据传递的$stateParam
填充范围变量——可能通过ajax 调用。
请记住 - 动态性质会因您尝试执行的操作而有很大差异。有很多方法可以利用child and nested states,也有很多方法可以利用add dynamic states - 真的 - 你可以在这里获得你想要的动态。最重要的是,按照以下示例中的意图利用ui-view
解决了滚动问题。观察以下,可能是动态的,可能是有利的例子......
<section class="container">
<aside>
<a ng-repeat="n in nav" ui-sref="slide('id': n.slide )">state: n.slide </a>
</aside>
<div ui-view><span>dynamic content</span></div>
</section>
.config(['$stateProvider', function($stateProvider)
$stateProvider
.state('slide', url: 'slide/:id', template: '<span> content </span>' )
])
.controller('ctrl', ['$scope', function($scope)
$scope.nav = [
'slide': 'a' , 'slide': 'b' , 'slide': 'c' ,
'slide': 'd' , 'slide': 'e' , 'slide': 'f' ,
'slide': 'g' , 'slide': 'h' , 'slide': 'i' ,
'slide': 'j' , 'slide': 'k' , 'slide': 'l'
];
$scope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams)
// - just to demo
// - use this param to get dynamic content
// - then populate scope variables in template
$scope.content = toParams.id;
);
]);
JSFiddle Link - 更动态的演示
【讨论】:
您的解决方案运行良好,但我的应用程序的状态是完全动态的(来自服务器)。是否可以动态使用 $stateProvider ?现在,我以 $scope.$emit 和 $scope.$broadcast 结束。以上是关于防止滚动 AngularJs 上动态更新的可滚动 div的主要内容,如果未能解决你的问题,请参考以下文章
带有 Angular Material 动态高度标签的可滚动内容元素
防止在Angular中的单个router.navigate调用上滚动到顶部