element-ui BackTop改造, 增加回到底部

该博客介绍了如何改造Element UI的BackTop组件,创建一个名为GoTopAndBottom的自定义组件,使其同时具备回到顶部和底部的功能。组件通过监听滚动事件并使用防抖函数优化性能,平滑滚动效果使用了缓动函数。在页面不同位置(顶部、中段、底部)显示组件的效果也进行了展示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<template>
  <div>
    <transition name="el-fade-in">
      <div
        v-if="toTopVisible"
        @click.stop="handleTopClick"
        :style="{
        'right': styleRight,
        'bottom': styletopBottom
      }"
        class="el-backtop">
        <slot name="top">
          <el-icon name="caret-top"></el-icon>
        </slot>
      </div>
    </transition>
    <transition name="el-fade-in">
      <div
        v-if="toBottomVisible"
        @click.stop="handleBottomClick"
        :style="{
        'right': styleRight,
        'bottom': stylebotBottom
      }"
        class="el-backtop">
        <slot name="bottom">
          <el-icon name="caret-bottom"></el-icon>
        </slot>
      </div>
    </transition>
  </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: 'GoTopAndBottom',

  props: {
    goTopVisibilityHeight: {
      type: Number,
      default: 200
    },
    tobotVisibilityHeight: {
      type: Number,
      default: 200
    },
    target: [String],
    right: {
      type: Number,
      default: 40
    },
    bottom: {
      type: Number,
      default: 40
    }
  },

  data() {
    return {
      el: null,
      container: null,
      toTopVisible: false,
      toBottomVisible:true,
    };
  },

  computed: {
    styletopBottom() {
      return `${this.bottom+25}px`;
    },
    styleRight() {
      return `${this.right}px`;
    },
    stylebotBottom() {
      return `${this.bottom-25}px`;
    },
  },

  mounted() {
    this.init();
    this.throttledScrollHandler = throttle(300, this.onScroll);
    this.container.addEventListener('scroll', this.throttledScrollHandler);
    this.onScroll();
  },

  methods: {
    init() {
      this.container = document;
      this.el = document.documentElement;
      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() {

      const scrollTop = this.el.scrollTop;
      this.toTopVisible = scrollTop >= this.goTopVisibilityHeight;
      this.toBottomVisible = (scrollTop + document.documentElement.clientHeight) <= (this.el.scrollHeight-this.tobotVisibilityHeight);
    },
    handleTopClick(e) {
      this.scrollToTop();
      this.$emit('toTopClick', e);
    },
    handleBottomClick(e) {
      this.scrollToTBottom();
      this.$emit('toBotClick', e);
    },
    scrollToTop() {
      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));
          console.log(beginValue);
          rAF(frameFunc);
        } else {
          el.scrollTop = 0;
        }
      };
      rAF(frameFunc);
    },
    scrollToTBottom() {
      const el = this.el;
      const beginTime = Date.now();
      const beginValue = el.scrollTop;
      const endScrollTop = el.scrollHeight-document.documentElement.clientHeight;
      const rAF = window.requestAnimationFrame || (func => setTimeout(func, 16));
      const frameFunc = () => {
        const progress = (Date.now() - beginTime) / 500;

        if (progress < 1) {
          el.scrollTop = (endScrollTop-beginValue) * easeInOutCubic(progress) + beginValue;
          rAF(frameFunc);
        } else {
          el.scrollTop = endScrollTop;
        }
      };
      rAF(frameFunc);
    }
  },

  beforeDestroy() {
    this.container.removeEventListener('scroll', this.throttledScrollHandler);
  }
};
</script>

改造element 中BackTop , 写成固定组件, 通过组件调用 ,页面效果与element区别不大。

引用组件:

import GoTopAndBottom from "@/components/GoTopAndBottom/index";

 效果图:
页面顶部

 

页面中段

 

页面底部:

 

转自:vue element-ui BackTop,el-backtop 改造,element 底部,拉到底部_奇怪的怪奇的博客-优快云博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值