功能背景:一个支付按钮在底部,由于上面的内容过多,将按钮挤出屏幕外,这样不利于支付转换,故需要这样一个功能。
兼容不支持requestAnimFrame的浏览器
window.requestAnimFrame = (() => {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
(callback => { window.setTimeout(callback, 1000 / 60) })
})()
监听滚动事件以及判定是否在屏幕内
// ele 按钮
// 执行的 是/否在屏幕时的处理,传入true/false
document.addEventListener('scroll', throttle(ele, callback), false)
throttle(ele, callback) {
let isRunning = false;
return () => {
if (isRunning) return; // 节流
isRunning = true;
// requestAnimationFrame:回调间隔 = 浏览器重绘频率
window.requestAnimationFrame((timestamp) => {
callback(checkEleHidden(ele));
isRunning = false
})
}
}
// 这里是根据按钮底部到屏幕距离,注意是屏幕
checkEleHidden(ele){
const bottom2top = ele.getBoundingClientRect().bottom
const height = window.innerHeight
return height < bottom2top
}
需要注意的是,进页面需要主动触发一下throttle,要不然只有触发滚动的时候才开始生效。
requestAnimationFrame的渲染是根据浏览器的性能来决定的,当页面运行在后台标签或者隐藏在iframe中会被暂停来提升性能,所以倒计时不能使用这个方式,精准倒计时的实例后面我会写出一个例子
requestAnimationFrame((timestamp)=>{
// timestamp 计算上一个回调函数的工作负载期间已经消耗了一些时间
})
requestAnimationFrame()的返回值是一个 long 整数,请求 ID ,一的标识。是个非零值,没别的意义。你可以传这个值是回调列表中唯一的标识是个非零值,没别的意义。你可以传这个值给 window.cancelAnimationFrame() 以取消回调函数。
欢迎关注我的公众号:朕惊前端
