这是我参与8月更文挑战的第8天,活动详情查看:8月更文挑战
基础组件最后一件:Backtop
回到顶部的野望
谈及前端开发中的基础交互,必不可少的一个功能应该就是回到顶部了吧,
但是Backtop
回到顶部功能应该也是网页中最不起眼的一个功能了,这句话没争议吧。
在我为数不多的开发经验当中,看过好几款不同的回到顶部,如瞬间回到顶部
,滚动回顶顶部
,定时回到顶部
这几种算是比较常见的了,其中尤以瞬回
,滚回
这两种方式最为常见,而定时回顶
则相对少一些,实现略微有点复杂,收益也不大,也就是传说中的付出大于回报。
当然这些都是看个人意愿,而在常规的Web项目
开发中,回到顶部大概是必不可少的啦,尤其是长页面的项目中。
基础组件这一块也就以这个组件来作为结尾,之后开始下一个分类的组件分享。
画虎先画骨。
这里还是先从结构讲起,回到顶部的结构比较简单,常规布局就可以,主要是通过一个值控制好它的显示隐藏就可以了。
<template lang="pug">
block content
div(
class="yx-backTop"
:style="{right: `${right}px`, bottom: `${bottom}px`}"
@click="toTop"
v-show="backTop" // 控制是否显示,这里切忌用v-if,属于一个小小小的优化。
)
slot
div.yx-backTop-content
<yx-icons type="backTop" />
</template>
结构比较简单,如果传值就显示传入样式,否则显示一个单纯的图标,默认样式也可以自定义一个啦。
逻辑部分
通过结构部分,就可以很清晰看到接受的传值了,那么这里只讲一下核心的内容,即定时回到顶部
的方法。
这个方法并非我自己写的,本来只是想用常规的滚动回顶的,但是思来想去,那样的话这个组件就没什么好些的了。所以经过我多方查阅,来回闹腾,终于在其他的组件库找到了类似的方法,所以这里只是简单的进行一波分析。
代码如下
onMounted(() => {
window.addEventListener('scroll', handleScroll, false)
window.addEventListener('resize', handleScroll, false)
})
onBeforeUnmount(() => {
window.removeEventListener('scroll', handleScroll, false)
window.removeEventListener('resize', handleScroll, false)
})
const handleScroll = () => {
backTop.value = window.pageYOffset >= props.showHeight;
}
const toTop = () => {
const sTop = document.documentElement.scrollTop || document.body.scrollTop;
scrollTop(window, sTop, 0, props.duration);
emits('click');
}
const scrollTop = (el, from = 0, to, duration = 500, endCallback) => {
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = (
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
return window.setTimeout(callback, 1000/60);
}
);
}
const difference = Math.abs(from - to);
const step = Math.ceil(difference / duration * 50);
function scroll(start, end, step) {
if (start === end) {
endCallback && endCallback();
return;
}
let d = (start + step > end) ? end : start + step;
if (start > end) {
d = (start - step < end) ? end : start - step;
}
if (el === window) {
window.scrollTo(d, d);
} else {
el.scrollTop = d;
}
window.requestAnimationFrame(() => scroll(d, end, step));
}
scroll(from, to, step);
}
核心方法就是这里的window.requestAnimationFrame
了, 正好前不久以为掘金大佬写过相关的文章# 一个神奇的前端动画 API requestAnimationFrame;
简单来说,就是requestAnimationFrame是一个不断重复执行的函数,会一直绘制屏幕,而这个函数要做的就是计算出要滚动的距离,以及每次执行时滚动的距离。
整个函数入口判断该API是否可用,之后计算当前滚动距离 减去 目标距离, 得出需要滚动的距离, 之后在计算每次执行时要滚动多少距离const step = Math.ceil(difference / duration * 50);
剩下的就是细化这个函数了。
到这就是整个核心函数要做的事情了。
其他的样式及结构是非常个性化的东西,就不去过多的强调我的做法了。
最后
截止到本文结束,已经是写完了这个组件库中大部分的基础组件,并且自认为基础的一些内容是都涵盖在文中,能满足其他任何类型(包括我没写过)的组件开发了。
那么从下文开始,就将正式进入到下一大类的组件分享了。敬请期待吧。
最后,在这里列一下基础组件列表: