在无限滚动中延迟加载时锁定滚动位置(向上滚动)

Posted

技术标签:

【中文标题】在无限滚动中延迟加载时锁定滚动位置(向上滚动)【英文标题】:Locking scroll position when lazy loading in infinite scroll (scroll up) 【发布时间】:2016-06-23 16:04:25 【问题描述】:

我的应用程序中有对话/类似 WhatsApp 的功能。最新消息在底部,最旧的消息在顶部。

当我在消息顶部附近滚动时,它会自动加载更多内容,但我想将滚动位置保持在原位。我创建了一个执行此操作的指令,但问题是它闪烁。似乎发生的是新消息被加载并且滚动位置被重置到顶部。然后我的指令启动并将滚动位置重置为原来的位置。所以它可以工作,但看起来不太好。

有人知道如何解决这个问题吗?

html

<div class="conversation-scroll-container" scroll-lock=" vm.isLoading ">

VM(加载消息功能):

return this.messageService
    .getMessages(conversation, dates)
    .then(data => 
        this.selectedConversation.applyNewMessages(data);

        return data;
    )
    .finally(() => 
            this.isLoading = false;
    );

最后是指令(在 TS 中):

export class ScrollLockDirective implements angular.IDirective 
    public restrict = "A";
    private scrollLock = false;
    private scrollLockOffset = 0;

    constructor(private $timeout: angular.ITimeoutService)  

    static factory(): ng.IDirectiveFactory 
        const directive = ($timeout: angular.ITimeoutService) => new ScrollLockDirective($timeout);

        directive.$inject = ["$timeout"];

        return directive;
    

    public link = (scope: angular.IScope, element: angular.IAugmentedJQuery, attributes: angular.IAttributes) => 

        attributes.$observe("scrollLock", () => 

            if (attributes["scrollLock"] === "true") 
                this.scrollLock = true;
            
            else 
                this.doLockScroll(element);
                this.scrollLock = false;
            
        );

        element.bind("scroll", () => 
            this.doLockScroll(element);
        );

        scope.$on("$destroy", () => 
            element.unbind("scroll");
        );
    

    private doLockScroll(element: angular.IAugmentedJQuery) 

        if (this.scrollLock) 
            this.$timeout(() => 
                element.scrollTop(element[0].scrollHeight - this.scrollLockOffset);
            );
         else 
            this.scrollLockOffset = element[0].scrollHeight - element.scrollTop();
        
    

【问题讨论】:

我在上面添加元素但想保留滚动位置时遇到了同样的闪烁问题。我想主要问题是我们需要在知道需要调整的高度之前让角度渲染 DOM。您找到解决方案了吗? 【参考方案1】:

我和你有同样的问题,我也尝试设置 scrollTop 位置等,但解决方案很简单:你只需要渲染新项目,而不是重新渲染所有项目。

【讨论】:

以上是关于在无限滚动中延迟加载时锁定滚动位置(向上滚动)的主要内容,如果未能解决你的问题,请参考以下文章

jQuery 无限滚动/延迟加载

ember.js 无限滚动(延迟加载)

JQuery浮动菜单栏,滚动位置和延迟

使用纯 JavaScript 的基本无限滚动/延迟加载博客文章

懒惰地加载 NSTableView

添加文本后的 Richtextbox 滚动位置