We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
本文为博客迁移过来,原文链接: 记录第一个vue组件 Backtop:2020-10-29
Backtop 作为一个不起眼的小组件,api也不会很多,最适合拿来当上手的小组件,这里是基于vue写的组件。
在写一个组件之前,我们要先考虑这个组件的api都有哪些,先把 props 列好,再规划组件怎么写就事半功倍
在做之前也参考了一些业界比较有名的组件库,比如 ant-design、element-ui
上面这些props都很好实现,这个组件的灵魂其实就只有 scrollTo 这个功能
scrollTo
我们可以单独实现一个scrollTo的公共函数,后面其他组件可以直接调用
在一般的情况下,如果只是默认回到顶部,没有滚动时间需求的话,用系统的api是最优选择MDN scroll-behavior
// 先判断是否支持该属性,不支持的话,会直接跳到目标位置没有动画 const isSuperScrollBehavior = 'scrollBehavior' in target.style isSuperScrollBehavior && target.scrollTo({ top, behavior: 'smooth' })
如果浏览器不支持(safari)或者我们需要控制滚动的时间怎么办呢? 这时候我们就得手动计算当前滚动值,然后赋值给 target.scrollTop 以达到滚动的效果 一般这种模拟动画执行我们都会用 rAF(requestAnimationFrame),对于不支持rAF的浏览器直接简单粗暴用 setTimeout(cb, 16) 来代替。
setTimeout(cb, 16)
滚动的动画我选的是 easeInOutCubic,关于其他的贝塞尔曲线实现可以看这个仓库bezier-easing
easeInOutCubic
最后再注意一下重复调用scrollTo的绑定问题就可以了
const sign = Symbol('elementScrollToEvent'); // 这里可以直接项目的规范不用Symbol // 缓动函数 const easeInOutCubic = t => t < .5 ? (t ** 3) * 4 : (t - 1) * ( 2 * t - 2) ** 2 + 1 const getScroll = (target, isTop) => { const isWindow = target === window; const props = isTop ? 'pageYOffset' : 'PageXOffset'; const methods = isTop ? 'scrollTop' : 'scrollLeft'; return target[isWindow ? props : methods]; }; function scrollTo(target, { top = 0, time } = {}) { const superScrollBehavior = 'scrollBehavior' in target.style; if (time || !superScrollBehavior) { const startTime = Date.now(); const startScrollTop = getScroll(target, true); const totalOffset = startScrollTop - top; if (target[sign]) { window.cancelAnimationFrame(target[sign]); } const frameFunc = () => { const progress = (Date.now() - startTime) / (time || 450); if (progress < 1) { target.scrollTop = startScrollTop - totalOffset * easeInOutCubic(progress); window.requestAnimationFrame(frameFunc); } else { target.scrollTop = top; } }; target[sign] = window.requestAnimationFrame(frameFunc); } else { target.scrollTo({ top, behavior: 'smooth' }); } }
The text was updated successfully, but these errors were encountered:
No branches or pull requests
Backtop 作为一个不起眼的小组件,api也不会很多,最适合拿来当上手的小组件,这里是基于vue写的组件。
在写一个组件之前,我们要先考虑这个组件的api都有哪些,先把 props 列好,再规划组件怎么写就事半功倍
在做之前也参考了一些业界比较有名的组件库,比如 ant-design、element-ui
上面这些props都很好实现,这个组件的灵魂其实就只有
scrollTo
这个功能ScrollTo
我们可以单独实现一个
scrollTo
的公共函数,后面其他组件可以直接调用scrollBehavior
在一般的情况下,如果只是默认回到顶部,没有滚动时间需求的话,用系统的api是最优选择MDN scroll-behavior
requestAnimationFrame
如果浏览器不支持(safari)或者我们需要控制滚动的时间怎么办呢?
这时候我们就得手动计算当前滚动值,然后赋值给 target.scrollTop 以达到滚动的效果
一般这种模拟动画执行我们都会用 rAF(requestAnimationFrame),对于不支持rAF的浏览器直接简单粗暴用
setTimeout(cb, 16)
来代替。滚动的动画我选的是
easeInOutCubic
,关于其他的贝塞尔曲线实现可以看这个仓库bezier-easing最后再注意一下重复调用scrollTo的绑定问题就可以了
The text was updated successfully, but these errors were encountered: