回到页面顶部(回到顶部、过渡动画)

发布时间 2023-12-02 11:08:16作者: xiao旭

项目背景:
vue

1.创建 backtop.vue 的回到顶部逻辑的组件
<template>
  <transition name="back-up-fade">
    <div
      class="back-top"
      :style="{
        bottom: bottom + 'px',
        right: right + 'px',
      }"
      @click.stop="handleBackTopClick($event)"
      v-if="show"
    >
      <div class="back-text-contaner card">
        <!-- 提供了插槽显示插槽内容 -->
        <slot v-if="$slots.default"></slot>
        <!-- 没提供,使用默认的 -->
        <div class="default-text" v-else>
          up
        </div>
      </div>
    </div>
  </transition>
</template>

<script>
// 导入节流函数
// import { throttle } from "./utils";
 let throttle=function(fn, intervalTime = 200, immediate = true) {
  let oldTime = Date.now();
  return function (...arg) {
    if (immediate) {
      fn.bind(this)(...arg);
      immediate = false;
    }
    let nowTime = Date.now();
    if (nowTime - oldTime >= intervalTime) {
      fn.bind(this)(...arg);
      oldTime = nowTime;
    }
  };
}

export default {
  props: {
    // 触发滚动的容器
    target: {
      type: String,
      default: "",
    },
    // 滚动高度达到此参数值才出现
    visibilityHeight: {
      type: Number,
      default: 100,
    },
    // 控制其显示位置, 距离页面右边距
    right: {
      type: Number,
      default: 270,
    },
    // 控制其显示位置, 距离页面底部距离
    bottom: {
      type: Number,
      default: 60,
    },
  },
  data() {
    return {
      // 滚动容器
      container: null,
      // 是否显示
      show: false,
      // 定时器标识
      timer: null,
      // 包裹元素节点
      el: "",
    };
  },
  mounted() {
    //节流处理,避免频繁触发事件
    this.throttleHandleContanierScroll = throttle(
      this.handleContanierScroll,
      10,
      false
    );
    this.init();
  },
  methods: {
    init() {
      // 默认滚动元素为document
      this.container = document;
      this.el = document.documentElement;
      // 外部传入滚动包裹元素时候
      if (this.target) {
        const el = document.querySelector(this.target);
        el ? (this.container = el && (this.el = el)) : null;
      }
      // console.log(this.container);
      this.container.addEventListener(
        "scroll",
        this.throttleHandleContanierScroll,
        false
      );
    },
    // 回到顶部点击
    handleBackTopClick(e) {
      // 给回到顶部一定过度事件
      console.log(e,'>>>>>>>>');
      this.timer = setInterval(() => {
        this.scrollToTop();
      }, 16);
      // 通知用户
      this.$emit("backUpClick", e);
    },
    // 滚动事件
    handleContanierScroll() {
      // 滚动超出给定高度则显示,否则隐藏
      if (this.el.scrollTop > this.visibilityHeight) {
        this.show = true;
      } else {
        this.show = false;
      }
    },
    // 滚动到顶部
    scrollToTop() {
      if (this.el.scrollTop > 0) {
        this.el.scrollTop -= 50;
      } else {
        clearInterval(this.timer);
      }
    },
  },
  beforeDestroy() {
    // 销毁定时器
    clearInterval(this.timer);
    this.timer = null;
  },
};
</script>

<style lang="scss">
.back-top {
  // position: fixed;
  // background-color: #fff;
  // width: 40px;
  // height: 40px;
  background: rgba(226, 243, 255, 0.8);
  border-radius: 10px 10px 10px 10px;
  border: 1px solid #BADAFD;
  padding: 10px;
  opacity: 1;

  // border-radius: 50%;
  color: #409eff;
  display: flex;
  align-items: center;
  justify-content: center;
  // font-size: 20px;
  // box-shadow: 0 0 6px rgb(0 0 0 / 12%);
  cursor: pointer;
  z-index: 999;
}
.back-up-position {
  position: relative;
}

// 过度动画
.back-up-fade-enter-active {
  transition: opacity 0.3s linear;
}
.back-up-fade-enter {
  opacity: 0;
}
.back-up-leave-to {
  opacity: 0;
}
</style>

2.在相应的组件位置进行引用
//引入组件
import backtop from "./backtop.vue";

//注册组件
components: { backtop },

//组件使用
<backtop :visibility-height="200" @backUpClick="handleBackUpClick">
   <img src="@/assets/images/mh/fwback.png" alt="">
   <span>回到顶部</span>
</backtop>

backUpClick 为点击按钮回到顶部后触发的事件

进行组件封装 可以与业务代码进行解耦,预留插槽位置可以保留外部的样式定制化,预留外部api的定制化操作。