仿照el-backtop回到底部,来一个回到顶部

89 阅读1分钟

别问,问就是客户要求有这个功能 话不多说,直接上代码

<template>
    <transition name="el-fade-in-linear">
      <div
        v-show="visible"
        class="el-bottom"
        @click="handleScrollToBottom"
      >
      <el-icon ><CaretBottom /></el-icon>
      </div>
    </transition>
  </template>
  
  <script>
  export default {
    name: 'ElBottom',
    props: {
      target: {
        type: String,
        default: ''
      },
      visibilityHeight: {
        type: Number,
        default: 200
      }
    },
    data() {
      return {
        visible: false,
        el: null,
        scrollListener: null
      };
    },
    mounted() {
      this.init();
    },
    beforeDestroy() {
      this.removeScrollListener();
    },
    methods: {
      init() {
        if (this.target) {
          this.el = document.querySelector(this.target);
        } else {
          this.el = window;
        }
  
        this.addScrollListener();
      },
      addScrollListener() {
        this.scrollListener = () => {
          this.visible = this.getScrollTop() > this.visibilityHeight;
        };
        this.el.addEventListener('scroll', this.scrollListener);
      },
      removeScrollListener() {
        if (this.scrollListener) {
          this.el.removeEventListener('scroll', this.scrollListener);
        }
      },
      getScrollTop() {
        if (this.el === window) {
          return Math.max(window.pageYOffset || 0, document.documentElement.scrollTop);
        }
        return this.el.scrollTop;
      },
      handleScrollToBottom() {
        const el = this.el === window ? document.documentElement : this.el;
        const totalScrollDistance = el.scrollHeight - el.clientHeight;
        this.scrollTo(totalScrollDistance, 500);
      },
      scrollTo(distance, duration) {
        const startTime = Date.now();
        const startScroll = this.getScrollTop();
        const change = distance - startScroll;
  
        const animateScroll = () => {
          const currentTime = Date.now();
          const currentTimeElapsed = currentTime - startTime;
          const progress = Math.min(currentTimeElapsed / duration, 1);
  
          this.el.scrollTop = startScroll + change * progress;
  
          if (progress < 1) {
            requestAnimationFrame(animateScroll);
          }
        };
  
        animateScroll();
      }
    }
  };
  </script>
  
  <style scoped>
  .el-bottom {
    position: fixed;
    bottom: 20px;
    right: 20px;
    width: 40px;
    height: 40px;
    line-height: 40px;
    text-align: center;
    background-color: #ffffff;
    border-radius: 50%;
    box-shadow: 0 0 6px rgba(0, 0, 0, 0.12);
    cursor: pointer;
    z-index: 1000;
    color: #0070FF;
  }
  
  .el-bottom i {
    font-size: 20px;
    /* color: #909399; */
  }
  
  .el-bottom:hover {
    background-color: #ebebeb;
  }
  </style>
  1. 模板部分

    • <div class="content"> 包含了页面的主要内容,这里用了一个简单的循环生成多行内容,以便滚动。
    • <el-bottom target=".content"> 是 el-bottom 组件,target 属性指定了需要监听滚动的元素选择器。
  2. 脚本部分

    • 导入 ElBottom 组件并在 components 中注册。
    • 定义了一个简单的 Vue 组件,没有额外的数据或方法。
  3. 样式部分

    • 为 .content 设置了一个固定的高度和滚动条,以便能够滚动并触发 el-bottom