当鼠标在container容器中滚动高度 间隔container顶部 超过400px时,回到顶部按钮会展现,点击按钮会回到container顶部
父组件:
<template> <div class="container"> <back-top target=".container" :visibility-height="400"> </back-top> <div class="content"></div> </div></template><script>import BackTop from "@/components/BackTop";export default { components: { "back-top": BackTop, }, data() { return {}; },};</script><style scoped>.container { height: 300px; background-color: aqua;}.content { height: 1000px;}</style>
子组件:
<template> <div v-if="visible" class="el-backtop" @click.stop="handleClick()" :style="{ bottom: styleBottom, right: styleRight }" > <slot><i class="el-icon-arrow-up"></i></slot> </div></template><script>import throttle from "throttle-debounce/throttle";const cubic = (value) => Math.pow(value, 3);const easeInOutCubic = (value) => value < 0.5 ? cubic(value * 2) / 2 : 1 - cubic((1 - value) * 2) / 2;export default { name: "BackTop", props: { target: String, visibilityHeight: { type: Number, default: 200, }, bottom: { type: Number, default: 40, }, right: { type: Number, default: 40, }, }, data() { return { el: null, container: null, visible: false, }; }, computed: { styleBottom() { return `${this.bottom}px`; }, styleRight() { return `${this.right}px`; }, }, created() {}, mounted() { this.init(); this.throttledScrollHandler = throttle(300, this.onScroll); this.container.addEventListener("scroll", this.throttledScrollHandler); }, methods: { init() { if (this.target) { this.el = document.querySelector(this.target); if (!this.el) { throw new Error(`target is not existed: ${this.target}`); } this.container = this.el; } }, onScroll() { this.visible = this.el.scrollTop >= this.visibilityHeight; }, handleClick() { const el = this.el; const beginTime = Date.now(); const beginValue = el.scrollTop; const rAF = window.requestAnimationFrame || ((func) => setTimeout(func, 16)); const frameFunc = () => { const progress = (Date.now() - beginTime) / 500; if (progress < 1) { el.scrollTop = beginValue * (1 - easeInOutCubic(progress)); rAF(frameFunc); } else { el.scrollTop = 0; } }; rAF(frameFunc); }, },};</script><style>.x-backtop { position: fixed;}</style>