最新包含 Blink 的浏览器(如 Chrome、Opera)中的奇怪滚动行为
Posted
技术标签:
【中文标题】最新包含 Blink 的浏览器(如 Chrome、Opera)中的奇怪滚动行为【英文标题】:Weird scroll behavior in latest Blink-included browsers (like Chrome, Opera) 【发布时间】:2017-12-13 05:25:28 【问题描述】:最近我一直在为 Angular 构建一个树视图组件库,作为ngx-tree。
问题
在我想出了如何为这个库实现一个虚拟滚动功能以提高大数据集的性能并让它在 Firefox 中正常运行后不久,我就被一种奇怪的滚动行为所困在Blink-included 浏览器(如 Chromium、Chrome、Opera)中。
演示链接
这是演示 plunkr --
https://embed.plnkr.co/xMpmK5EBC46tDKpYFpw8请参阅下面的更新 #1
情况
在 Firefox、Edge 和 IE 11 中,我的具有虚拟滚动功能的库可以正常滚动。 但是,在 Chrome 和 Opera 中,当我滚动到树视图内的某些位置时,滚动条的位置(即滚动区域的scrollTop
属性)会上下跳动,导致 闪烁 树状视图并分解虚拟滚动功能。
浏览器详细版本
铬 - 59.0.3071.115 火狐 - 54.0 边缘 - 40.15063.0.0其他浏览器
在中国,有一些加壳浏览器衍生自Chromium项目(如360se、QQ浏览器、搜狗浏览器、UC浏览器)旧版本V8和Blink。而且他们没有那种奇怪的滚动行为。
一些假设
是不是 Chromium 团队对滚动实现进行了一些优化(比如平滑滚动)?
希望得到一些指导!!! (≧﹏≦)
更新 #1
带有事件日志的演示链接更新:https://embed.plnkr.co/GpQBZsguhZZOQWWbZnqI/
在打开 devtool 之前必须测试滚动才能查看日志
我必须再解释一下虚拟滚动的工作原理以及导致闪烁的原因。
首先,查看design of Virtual Scrolling。
虚拟滚动的一个关键点是,我们创建一个与该区域相同大小的假滚动区域,而没有虚拟滚动检测。所以在最佳情况下,滚动区域的滚动条位置不应该改变,直到某些预期事件触发它的改变。对于滚动事件,我们更新每个动画帧的视图。
在固定高度的滚动区域内,我们假设 scrollTop 属性不会以很大的百分比变化,如果我们正确模拟那些未渲染元素的高度(可能有 动画帧内的计算精度有点偏差)。
但是,根据我观察到的结果,blink 系列浏览器似乎执行了不同的策略来更新可滚动元素的 scrollTop。它更新 scrollTop 的时机与非闪烁系列浏览器不同。到目前为止,我已经想通了。
GIF 示例
这里我制作了一些 gif 来展示 Chrome、Firefox 和 Edge 的输出。
铬
火狐
边缘
【问题讨论】:
几乎没有分析,似乎函数setNative(zone.js)中的一个错误有某种处理requestAnimationFrame,但它需要更多挖掘。发起者是在 zone.js:1522 (v0.8.11) 处对 setNative.apply(window, args) 的反复调用。这也可能是与其他库混合造成的,但是当其他浏览器工作时... 我应该提一下,我在 Chromium 问题跟踪器 bugs.chromium.org/p/chromium/issues/detail?id=727239 中发现了一个相关问题 @bigless,但我很高兴你为这个问题提供了另一个视角。 我什至无法运行提供的演示 plunkr 您是否尝试在chrome://flags/
中禁用smooth scrolling
?
【参考方案1】:
您正在从 virtual-scroll-demo-branch
分支中提取库:
'ngx-tree': 'https://rawgit.com/e-cloud/ngx-tree/virtual-scroll-demo-branch/src/lib',
那个分支是 master 后面的 105 次提交。它错误地将margin-top
设置在其中一个内部元素上。这是fixed in newer versions。
编辑:开发人员实际上在他们的commit message 中引用了这个 Stack Overflow 问题。
【讨论】:
其实我是开发者。是的,我使用另一种方法来避免这个问题。虽然那个分支有点老了,但核心算法几乎是一样的。It incorrectly sets margin-top
可能不正确,因为它适用于 edge 和 firefox。以上是关于最新包含 Blink 的浏览器(如 Chrome、Opera)中的奇怪滚动行为的主要内容,如果未能解决你的问题,请参考以下文章