Vue实现⼀个返回顶部backToTop组件最近在学习VUE。⾃⼰就在研究怎么⽤VUE实现⼀个组件的封装,今⽇就算留个笔记
前⾔
返回顶部这个功能⽤jq实现,好容易实现,⼀个animate配合scrollTo就搞定了
今天我们来试试vue封装⼀个原⽣js实现的返回顶部;
写起来够呛,借助github,看了别⼈的gist,稍微封装了下;
当然不是⽤scrollTo直接调位那种,没有过渡效果怎么说得过去!!还是捣⿎出来了.
废话不多说,看效果图…
效果图
实现思路
1. 过渡⽤的是requestAnimationFrame,这货只⽀持IE10+,所以必须做兼容
2. 滚动视图是window.pageYOffset,这货⽀持IE9+;
3. 为了让可控性更强,图标采⽤iconfont,具体瞅代码
你能学到什么?
1. 学到⼀些页⾯计算相关的东东
2. 动画API的⼀些知识
3. Vue封装组件相关知识和⽣命周期和事件监听销毁相关知识的运⽤
实现功能
1. 视图默认在350处显⽰返回顶部的按钮和图标
2. 提⽰⽂字和颜⾊,在图标上下左右的⾃定义,字段都限制了格式和默认值
3. 图标颜⾊和形状,⼤⼩的⾃定义,字段都限制了格式和默认值
4. 过渡动效的⾃定义,⽤法:scrollIt(0, 1500, 'easeInOutCubic', callback);
1. 返回到视图的point,也就是滚动到哪⾥
2. 过渡时间(ms级别)
3. ⼀堆过渡效果,字符串格式,其实就是滚动的计算函数..
vue与react面试题4. 当然少不了默认参数了,除了callback
5. 兼容性是IE9+,特意开了虚拟机去尝试
代码
scrollIt.js –过渡滚动实现
export function scrollIt(
destination = 0,
duration = 200,
easing = "linear",
callback
)
{
// define timing functions -- 过渡动效
let easings = {
// no easing, no acceleration
linear(t) {
return t;
},
// accelerating from zero velocity
easeInQuad(t) {
return t * t;
},
/
/ decelerating to zero velocity
easeOutQuad(t) {
return t * (2 - t);
},
// acceleration until halfway, then deceleration
},
// accelerating from zero velocity
easeInCubic(t) {
return t * t * t;
},
// decelerating to zero velocity
easeOutCubic(t) {
return --t * t * t + 1;
},
// acceleration until halfway, then deceleration
easeInOutCubic(t) {
return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
},
// accelerating from zero velocity
easeInQuart(t) {
return t * t * t * t;
},
/
/ decelerating to zero velocity
easeOutQuart(t) {
return 1 - --t * t * t * t;
},
// acceleration until halfway, then deceleration
easeInOutQuart(t) {
return t < 0.5 ? 8 * t * t * t * t : 1 - 8 * --t * t * t * t;
},
// accelerating from zero velocity
easeInQuint(t) {
return t * t * t * t * t;
},
// decelerating to zero velocity
easeOutQuint(t) {
return 1 + --t * t * t * t * t;
},
// acceleration until halfway, then deceleration
easeInOutQuint(t) {
return t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * --t * t * t * t * t;
}
};
// requestAnimationFrame()的兼容性封装:先判断是否原⽣⽀持各种带前缀的 //不⾏的话就采⽤延时的⽅案
(function() {
var lastTime = 0;
var vendors = ["ms", "moz", "webkit", "o"];
for (var x = 0; x < vendors.length && !questAnimationFrame; ++x) { questAnimationFrame =
window[vendors[x] + "RequestAnimationFrame"];
window.cancelAnimationFrame =
window[vendors[x] + "CancelAnimationFrame"] ||
window[vendors[x] + "CancelRequestAnimationFrame"];
}
if (!questAnimationFrame)
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() {
callback(currTime + timeToCall);
}, timeToCall);
lastTime = currTime + timeToCall;
return id;
};
if (!window.cancelAnimationFrame)
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
})();
function checkElement() {
// chrome,safari及⼀些浏览器对于documentElemnt的计算标准化,reset的作⽤ document.documentElement.scrollTop += 1;
let elm =
document.documentElement.scrollTop !== 0
document.documentElement
: document.body;
}
let element = checkElement();
let start = element.scrollTop; // 当前滚动距离
let startTime = w(); // 当前时间
function scroll() { // 滚动的实现
let now = w();
let time = Math.min(1, (now - startTime) / duration);
let timeFunction = easings[easing](time);
element.scrollTop = timeFunction * (destination - start) + start;
if (element.scrollTop === destination) {
callback; // 此次执⾏回调函数
return;
}
}
scroll();
}
backToTop.vue
<template>
<div class="back-to-top" @click="backToTop" v-show="showReturnToTop" @mouseenter="show" @mouseleave="hide">
<i :class="[bttOption.iClass]" :></i>
<span class="tips" :class="[bttOption.iPos]" : v-show="showTooltips">{{}}</span> </div>
</template>
<script>
import { scrollIt } from './scrollIt'; // 引⼊动画过渡的实现
export default {
name: 'back-to-top',
props: {
text: { // ⽂本提⽰
type: String,
default: '返回顶部'
},
textColor: { // ⽂本颜⾊
type: String,
default: '#f00'
},
iPos: { // ⽂本位置
type: String,
default: 'right'
},
iClass: { // 图标形状
type: String,
default: 'fzicon fz-ad-fanhuidingbu1'
},
iColor: { // 图标颜⾊
type: String,
default: '#f00'
},
iFontsize: { // 图标⼤⼩
type: String,
default: '32px'
},
pageY: { // 默认在哪个视图显⽰返回按钮
type: Number,
default: 400
},
transitionName: { // 过渡动画名称
type: String,
default: 'linear'
}
},
data: function () {
return {
showTooltips: false,
showReturnToTop: false
}
bttOption () {
return {
text: ,
textColor: Color,
iPos: this.iPos,
iClass: this.iClass,
iColor: this.iColor,
iFontsize: this.iFontsize
}
}
},
methods: {
show () { // 显⽰隐藏提⽰⽂字
return this.showTooltips = true;
},
hide () {
return this.showTooltips = false;
},
currentPageYOffset () {
// 判断滚动区域⼤于多少的时候显⽰返回顶部的按钮
window.pageYOffset > this.pageY ? this.showReturnToTop = true : this.showReturnToTop = false; },
backToTop () {
scrollIt(0, 1500, ansitionName, this.currentPageYOffset);
}
},
created () {
window.addEventListener('scroll', this.currentPageYOffset);
},
beforeDestroy () {
}
}
</script>
<style scoped lang="scss">
.back-to-top {
position: fixed;
bottom: 5%;
right: 100px;
z-index: 9999;
cursor: pointer;
width: auto;
i {
font-size: 32px;
display: inline-block;
position: relative;
text-align: center;
padding: 5px;
background-color: rgba(234, 231, 231, 0.52);
border-radius: 5px;
transition: all 0.3s linear;
&:hover {
border-radius: 50%;
background: #222;
color: #fff !important;
}
}
.tips {
display: inline-block;
position: absolute;
word-break: normal;
white-space: nowrap;
width: auto;
font-size: 12px;
color: #fff;
z-index: -1;
}
.left {
right: 0;
top: 50%;
margin-right: 50px;
transform: translateY(-50%);
.right {
left: 0;
top: 50%;
margin-left: 50px;
transform: translateY(-50%);
}
.bottom {
bottom: 0;
margin-top: 50px;
}
.top {
top: 0;
margin-bottom: 50px;
}
}
</style>
总结
从⼼⾎来潮到折腾出来,为了兼顾兼容性和拓展性,好像⼏个⼩时了.
不过实现了.你再搬到其他语⾔,类似ng4,也就是⼗来分钟的事情,
思路会了,实现更多的是写法⽽已,⾄于性能优化,可以⼀边写⼀边考虑,也可以实现后有空再优化. 希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论