【问题标题】:How to debounce or throttle scroll events in iOS devices ( Safari )如何在 iOS 设备 (Safari) 中去抖动或限制滚动事件
【发布时间】:2023-04-08 13:23:02
【问题描述】:

我正在尝试为移动和桌面设备实现无限滚动下拉菜单。在“无限滚动”下,我的意思是以下 - 如果您有 100 条记录,当到达可滚动容器的末尾时,将加载 20 条新记录并隐藏前 20 条记录(向后方向相同)

我遇到了以下问题:

除了 Safari 移动浏览器(iPhone、iPad 等)之外,一切都可以在移动 Android Chrome 浏览器 + 桌面浏览器中完美运行

我尝试了以下解决方案:

  • 在整个滚动处理函数中添加了 lodash debounce/throttle 函数,这没有帮助,甚至到处都破坏了滚动

  • 我尝试使用 iScroll,但遇到了与此处相同的问题 + iscroll scrollTo() 方法的其他错误。

  • requestAnimationFrame() - 没有任何成功。

这是我的示例项目: https://jsfiddle.net/q4nLverg/2/

滚动处理函数代码:

function scrollHandler(e) {

    var top = $(this.$refs.dropdownContainer).scrollTop();
    var difference = $(this.$refs.dropdownMenu).height() - $(this.$refs.dropdownContainer).height()

    if (top >= difference - this.scrollLimit && difference > 0) {

        this.maxRowsLimitIndex = this.maxRowsLimitIndex + this.numberOfItemsToLoad;
        this.minRowsLimitIndex = this.minRowsLimitIndex + this.numberOfItemsToLoad

        if ( this.maxRowsLimitIndex >= this.options.length ) {

            this.maxRowsLimitIndex = this.options.length
            this.minRowsLimitIndex = this.options.length - this.numberOfVisibleItems
        }
        else {
            this.scrollTo( (difference - (this.numberOfItemsToLoad * 28)) )
        }
    }
    else if ( top <= this.scrollLimit )
    {
        this.maxRowsLimitIndex = this.maxRowsLimitIndex - this.numberOfItemsToLoad;
        this.minRowsLimitIndex = this.minRowsLimitIndex - this.numberOfItemsToLoad

        if ( this.maxRowsLimitIndex <= this.numberOfVisibleItems  ) {
            this.maxRowsLimitIndex = this.numberOfVisibleItems
            this.minRowsLimitIndex = 0
        }
        else {
            this.scrollTo( (this.numberOfItemsToLoad * 28)/2)
        }

    }
}

this.scrollTo - 只是更改容器的 scrollTop 以模拟在加载新数据并从选择中删除旧数据时自动向上或向下滚动

iOS 设备(和任何其他设备)中的预期结果:

当用户快速滚动到可滚动容器的末尾时,它不应该到达可滚动容器的末尾,但它必须继续滚动事件并因此加载数据(就像它在 android 设备中的工作方式一样)模拟无限滚动功能。

【问题讨论】:

    标签: javascript ios scroll safari


    【解决方案1】:

    如果所有行的高度相同,您可以尝试计算滚动区域的初始高度,并使用Intersection Observer 确定哪些行可见。

    【讨论】:

    • 如果我正确理解 Intersection Observer 的工作原理,它需要始终在 DOM 中呈现所有元素,但我有必须同时显示 65k+ 行的情况 - 为此我这样做在我需要显示它们之前,不要在 DOM 中渲染它们。
    • 你需要的东西叫做虚拟卷轴。你可以搜索看看这是如何在某些包中实现的,例如这个:github.com/Akryum/vue-virtual-scroller。由于加速滚动,您应该避免在移动设备的滚动上绑定侦听器,这就是我将您指向 Intersection 观察者的原因。
    猜你喜欢
    • 2016-07-24
    • 2021-10-24
    • 1970-01-01
    • 2012-07-13
    • 2022-06-12
    • 2018-11-26
    • 1970-01-01
    • 2015-04-12
    • 1970-01-01
    相关资源
    最近更新 更多