滚动事件
addEventListener 使用 passive 改善的滚屏性能
根据规范,passive 选项的默认值始终为false。但是,这引入了处理某些触摸事件(以及其他)的事件监听器在尝试处理滚动时阻止浏览器的主线程的可能性,从而导致滚动处理期间性能可能大大降低。
为防止出现此问题,某些浏览器(特别是Chrome和Firefox)已将文档级节点 Window,Document和Document.body的touchstart (en-US)和touchmove (en-US)事件的passive选项的默认值更改为true。这可以防止调用事件监听器,因此在用户滚动时无法阻止页面呈现。
var elem = document.getElementById('elem');
elem.addEventListener('touchmove', function listener() { /* do something */ }, { passive: true });
Copy to Clipboard
添加passive参数后,touchmove事件不会阻塞页面的滚动(同样适用于鼠标的滚轮事件)
您可以通过将passive的值显式设置为false来覆盖此行为,如下所示:
/* Feature detection */
/*特征检测*/
var passiveIfSupported = false;
try {
window.addEventListener("test", null, Object.defineProperty({}, "passive", { get: function() { passiveIfSupported = { passive: true }; } }));
} catch(err) {}
window.addEventListener('scroll', function(event) {
/* do something */
// can't use event.preventDefault();
// 不能使用 event.preventDefault()
}, passiveIfSupported );
在不支持addEventListener()的options参数的旧浏览器上,尝试使用它会阻止使用useCapture参数而不正确使用特征检测。
您无需担心基本scroll (en-US) 事件的passive值。由于无法取消,因此事件监听器无法阻止页面呈现。
问题-ios滚动卡顿不流畅?
解决方案
- body、局部滚动容器添加
-webkit-overflow-scrolling:touch
-webkit-overflow-scrolling
auto
:使用普通滚动, 当手指从触摸屏上移开,滚动会立即停止。touch
: 使用具有回弹效果的滚动,当手指从触摸屏上移开,内容会继续保持一段时间的滚动效果。继续滚动的速度和持续的时间和滚动手势的强烈程度成正比。同时也会创建一个新的堆栈上下文。
在移动端上,在你用overflow-y:scroll
属性的时候,你会发现滚动的效果很很生硬,很慢,这时候可以使用-webkit-overflow-scrolling:touch
这个属性,让滚动条产生滚动回弹的效果,就像ios原生的滚动条一样流畅。
问题-ios偶现滚动时最底部的内容被固定的tab菜单栏遮挡
尝试解决方案
- 父级元素的滚动容器添加
-webkit-overflow-scrolling:touch
(未复现),但是这种方案, ios(13.1.3)最外层会默认出现滚动条,如不需出现滚动条的,需手动在最外层添加隐藏滚动条的样式
-webkit-scrollbar {
display: none;
}
- 父级元素的底部添加
paddingBottom
,外层默认会增多一部分空白,不友好
问题-ios滚动到指定位置,出现部分组件渲染空白,滚动后正常显示,或滚动后部分元素渲染被截断
ios 11(13.1.3),当页面点击顶部的关键字或底部输入框输入关键字时,可出现查询的结果卡片,多次查询后,从顶部点击关键字直接滚动到最新的结果卡片时,结果卡片出现渲染异常(部分/全部元素渲染不出),来回滚动后,元素出现。
尝试解决方案
- 滚动到底部位置时,加一个定时器 (复现)
- 取消父级元素的
overflow:hidden
(复现) - 强制渲染子元素的内容 (复现)
- 父级元素的滚动容器添加
-webkit-overflow-scrolling:touch
(复现) - 添加
wil-change:scroll-position
(复现) - 父级元素及子元素添加最小高度 (复现,出现频率降低)
- 父元素滚动前设置
-webkit-overflow-scrolling:touch
, 滚动结束后设置-webkit-overflow-scrolling:touch
(同一种组件未出现,2种组件交替出现时复现、无效) - 父元素设置
backface-visibility: hidden;transform: translate3d(0,0,0);
(复现) 父元素取消
z-index
设置,同时添加-webkit-overflow-scrolling:auto
; (同一种组件或不同种组件交替出现时,均不再出现)小结
-webkit-overflow-scrolling:touch
这个属性添加后可能会引起一些奇奇怪怪的bug,上述是可能是由于层级z-index的设置或者是组件元素的不一致(试过用同一种组件,但是取消了单个结果的轮播点切换,复现),导致在视觉上渲染被遮挡的问题。
上述的几种情况是依据当时bug复现不同的表现而排查的步骤,最终还是得根据不同情况来修复问题。
问题-ios容器列表初始不能上滑加载更多数据,需下拉刷新后才能触发上滑加载更多
当设置了overflow-y:auto
的滚动容器高度减少一定的像素时,复现该问题, 但是要注意减少的容器高度,不然会引起最后一个列表元素的部分内容被遮挡。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。