防止滚动 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-routerui-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调用上滚动到顶部

具有固定标头的可滚动表格式化问题

MobileSafari(iOS Safari):有没有办法防止水平/垂直滚动“捕捉”?

在AngularJS中的滚动事件上获取鼠标位置

在AngularJS中的滚动事件上获取鼠标位置