节流函数是防止短时间内多次触发的一个处理函数
如:滚动事件,使用 addEventListener 方式添加监听器
window.addEventListener( "scroll",
throttle(
() => {
const scrollTop = window.scrollY;
// dosomething
}
)
)
function throttle(action, wait=1000) {
let time = Date.now()
return function () {
if (time + wait - Date.now() < 0) {
action();
time = Date.now()
}
}
}
为了使节流之后滚动更加的平滑, 我们可以使用 window.requestAnimationFrame() 来实现节流函数
function throttle (action){
let call = false;
return function () {
call = true;
window.requestAnimationFrame(
() => {
action()
call = false
}
)
}
}
在视窗中显示
当需要实现图片的懒加载或者是无限滚动时,需要确定元素是否出现在视窗中, 这样需要获取 elem.getBoundingClientRect();
window.addEventListener ( "scroll", () => {
const {bottom, right, left, top} = elem.getBoundingClientRect();
const inViewport = bottom > 0 && right > 0 && left < window.innerWidth && top < window.innerHeight;
注意: 每次调用 getBoundingClientRect 时都会触发回流, 这样会严重的影响性能,特别是在事件处理函数中,会更加的严重影响性能;
在 2016 年之后, 可以通过 Intersection Observer 这个 api 来解决问题, 它允许你追踪目标元素与其祖先元素或者视窗的交叉状态, 另外只有一部分元素出现在视窗中,哪怕只有 1 px , 也可以选择触发回调函数
const observer = new IntersectionObserver (callback, options);
observer.observe(element);
滚动边界的问题:
当用户滚到末尾时, 整个页面都会开始滚动;
连锁滚动的表现, 当滚动有;元素到达底部时,可以改变页面的 overflow 属性或者在滚动元素的滚动事件处理函数中取消默认行为来解决这个问题
如果使用 JavaScript 处理, 那么处理的不是 scroll 事件, 而是每当用户使用鼠标滚轮 或者 是触摸板时 触发的是 wheel 事件
过度滚动对移动端的影响尤为的严重,下拉刷新的手势在 安卓的chrome 浏览器中,问题出现了,它会刷新整个页面, 而不是加载更多的内容;这个就会产生很多问题;
css 通过 overscroll-behavior 这个新属性解决问题。它通过控制元素滚动到尽头时的行为来解决 下拉刷新与 连锁滚动带来的问题。安卓的 glow 与苹果中的 rubber band。
.element {
overscroll-vehavior: contain;
}
准确的说, IE 与 Edge 实现了独有的 -ms-scroll-chaining 属性来控制连锁滚动;
微软浏览器已经准备实现 overscroll-behavior 这个属性
触屏之后
在触屏设备上,滚动的体验是一个很大的话题。
苹果公司开发了 惯性 滚动的专利;
css 有一个很hack 的方法;
.element {
-webkit-overflow-scrolling: touch;
}
只支持 webkit 内核,
但是我们会使用 touch 事件来解决这个问题,但是这个会对用户滚动体验造成很大的影响;
在现代的浏览器中,虽然知道如何使滚动变得平滑,但为了 确定滚动事件处理函数中是否执行了 阻止默认事件 ;可能任会花费 500 mm 来等待事件处理函数执行完毕
即使是一个空的事件监听函数, 从不取消任何行为,鉴于浏览器会期待 preventDefault 的调用, 也会对性能造成影响
为了告诉浏览器不去检测事件是否阻止了默认事件,在 whatwg dom 标准中,存在一个特性,来解决这个事件,
elem.addEventListener('event', e => {
dosomething
}, {passive: true }
)
这个视频会看到带来的性能提升: https://www.youtube.com/watch?v=NPM6172J22g