Live2d Test Env

【论术】 复盘-回顶按钮以及功能

项目的回顶按钮以及功能,顺滑滚动/当前处于第一屏内不展示

<template>
  <div class="back-top" :class="{ visible: isVisible }">
    <a @click="scrollToTop" title="回到顶部">
      <SvgIcon iconClass="arrowTop" style="font-size: 22px; color: #fff" />
    </a>
  </div>
</template>

<script>
import SvgIcon from "@/components/SvgIcon.vue";
export default {
  name: "BackToTop",
  props: {
    // 要监听的滚动元素ID
    scrollElementId: {
      type: String,
      required: true,
    },
    // 滚动阈值,超过此值显示按钮
    scrollThreshold: {
      type: Number,
      default: 50,
    },
    // 滚动动画持续时间(毫秒)
    scrollDuration: {
      type: Number,
      default: 500,
    },
  },
  components: {
    SvgIcon,
  },
  data() {
    return {
      isVisible: false,
      scrollElement: null,
    };
  },
  mounted() {
    // 获取滚动元素
    this.scrollElement = document.getElementById(this.scrollElementId);

    if (this.scrollElement) {
      // 添加滚动事件监听
      this.scrollElement.addEventListener("scroll", this.handleScroll);
    } else {
      console.warn(`BackToTop: 未找到ID为"${this.scrollElementId}"的元素`);
    }
  },
  beforeDestroy() {
    // 移除滚动事件监听
    if (this.scrollElement) {
      this.scrollElement.removeEventListener("scroll", this.handleScroll);
    }
  },
  methods: {
    handleScroll() {
      // 检查滚动位置
      this.isVisible = this.scrollElement.scrollTop > this.scrollThreshold;
    },
    scrollToTop() {
      // 平滑滚动到顶部
      const startPosition = this.scrollElement.scrollTop;
      const startTime = performance.now();

      const animateScroll = (currentTime) => {
        const elapsed = currentTime - startTime;
        const progress = Math.min(elapsed / this.scrollDuration, 1);

        // 使用缓动函数使滚动更自然
        const easeInOutCubic = (t) =>
          t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;

        this.scrollElement.scrollTop = startPosition * (1 - easeInOutCubic(progress));

        if (progress < 1) {
          requestAnimationFrame(animateScroll);
        }
      };

      requestAnimationFrame(animateScroll);
    },
  },
};
</script>

<style scoped>
.back-top {
  width: 46px;
  height: 46px;
  position: fixed;
  bottom: 60px;
  right: 14px;
  z-index: 1000;
  opacity: 0;
  transition: opacity 0.5s ease;
  pointer-events: none;
}

.back-top.visible {
  opacity: 1;
  pointer-events: auto;
}

.back-top a {
  display: block;
  width: 46px;
  height: 46px;
  background: #0052d9;
  text-align: center;
  height: 46px;
  border-radius: 50%;
  text-decoration: none;
  font-size: 28px;
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
  transition: all 0.3s ease;
  cursor: pointer;
}

/* 响应式设计 */
/* @media (max-width: 768px) {
  .back-top {
    bottom: 20px;
    right: 20px;
  }

  .back-top a {
    width: 46px;
    height: 46px;
    line-height: 46px;
    font-size: 24px;
  }
} */
</style>

父组件使用:
<BackUp scroll-element-id="homeRef" :scroll-duration="600" /> 

以上。

posted @ 2025-12-08 16:21  致爱丽丝  阅读(0)  评论(0)    收藏  举报