这次总结一下BackTop组件的使用。
当列表数据较多时,用户很可能因为阅读或查找内容已经将列表上滑至距离顶部很远了,现在想要回到页面顶部进行其它操作。
应该为用户提供一个BackTop,一键到达列表组件顶部。
BackTop通常习惯下是悬浮(固定)在页面的右下角位置,这个可以根据实际情况调整展示的位置。
由于该组件是悬浮展示的,不可避免可能对页面或列表内容有遮挡,所以建议一开始不展示BackTop,只有当用户上滑一定距离后再展示。
个人认为一般情况下滑动高度超出列表滚动容器的高度即可展示BackTop。
点击BackTop后需要将列表内容滚动到顶部,推荐使用平滑滚动的方式。
页面滚动方式
scrollTop
container.scrollTop = 0;,设置滚动容器的scrollTop属性为0,可以直接回到顶部。
scrollTo(x, y)
- x 相当于设置滚动容器的scrollLeft。
- y 相当于设置滚动容器的scrollTop。
container.scrollTo(0, 0),设置y参数为0,则相当于设置了scrollTop=0。
在个别低版本的安卓机(如:oppo r11 plus)上scrollTo有兼容性问题。
scrollTo(options)
- options是一个对象,可以包含以下参数:
-
top 相当于设置scrollTop
-
left 相当于设置scrollLeft
-
behavior 行为,允许的值:
值 说明 smooth 表示平滑滚动并产生过渡效果 instant 表示滚动会直接跳转到目标位置,没有过渡效果。 auto 默认,由浏览器决定是否要产生过渡效果😭
-
behavior设置为'smooth'目前也存在兼容性问题。
css属性scroll-behavior
想要实现滚动缓动效果,可以给滚动容器设置css属性scroll-behavior: smooth;。
由于直接给滚动容器加了该css属性,导致列表页面刷新时高度复位也呈现缓动的效果。
列表页面刷新高度复位是不需要滚动缓动效果的,在滚动前需要先设置scroll-behavior: auto;。
或者自己写(抄)一个缓动算法
// 先加速后减速
// @params duration 整个缓动的持续时间
// @params lasted 已持续的时间
// @params startValue 开始值,页面的滚动高度
// @params changeValue 变化值,高度归0,变化值为-startValue
// @return 返回当前变化后的值 即当前页面的滚动高度
function easeInOut(lasted, startValue, changeValue, duration) {
// 系数:已持续时间 比上 总持续时间的一半
lasted /= duration / 2;
// 未过半/前半段(In状态) 系数是逐渐增长的
if (lasted < 1) {
// 前半段系数是增长的(0-1之间),变化是指数级别递增的
return (changeValue / 2) * lasted * lasted + startValue;
}
// 进入后半段,系数应该是[1, 2]
// 减掉1,系数剩下[0, 1]
lasted--;
startValue += changeValue / 2;
// 这里也是以指数级在变化
return (-changeValue / 2) * (lasted * (lasted - 2)) + startValue;
}
function scrollTopSmoothly(el, duration = 300) {
const startValue = el.scrollTop;
const changeValue = -startValue;
const beginTime = Date.now();
let lasted = 0;
function scroll() {
// 已过去的时间
lasted = Date.now() - beginTime;
// lasted不能超出duration
if (lasted > duration) lasted = beginTime;
el.scrollTop = easeInOut(lasted, startValue, changeValue, duration);
// 结束
if (lasted > duration) return;
requestAnimationFrame(scroll);
}
scroll();
}