You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js如何使用方向键实现平滑滚动到页面中部、底部及返回顶部

Vue 方向键分段平滑滚动实现方案

该功能完全可以在 Vue 中实现,核心逻辑是监听键盘事件、维护滚动状态、调用原生平滑滚动API即可,以下是可直接运行的实现思路和代码示例:

实现思路

  • 页面挂载时绑定键盘keydown事件监听,页面销毁时移除监听避免内存泄漏
  • 维护一个状态变量标记当前所处的滚动位置:共3个档位,分别对应顶部(0%)、中部(50%)、底部(100%)
  • 按下向下方向键时按「顶部→中部→底部」顺序切换档位,按下向上方向键时按「底部→中部→顶部」顺序切换档位
  • 档位切换时调用window.scrollTo并设置behavior: 'smooth'实现平滑滚动效果

代码示例(Vue3)

<template>
  <!-- 页面容器高度设为200vh方便测试滚动效果 -->
  <div class="page-container" style="height: 200vh; background: linear-gradient(#ffffff, #2c3e50);">
    <!-- 此处放你的页面业务内容 -->
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'

// 滚动状态:0=顶部 1=中部 2=底部
const scrollStatus = ref(0)
// 动态获取页面可滚动总高度
const getPageScrollHeight = () => document.documentElement.scrollHeight - window.innerHeight

const handleKeydown = (e) => {
  // 只响应上下方向键,keyCode 38为上键、40为下键
  if (e.keyCode !== 38 && e.keyCode !== 40) return
  // 阻止方向键默认滚动行为
  e.preventDefault()

  // 按按键更新滚动档位
  if (e.keyCode === 40) {
    scrollStatus.value = Math.min(scrollStatus.value + 1, 2)
  } else {
    scrollStatus.value = Math.max(scrollStatus.value - 1, 0)
  }

  // 计算目标滚动位置
  let targetScrollTop = 0
  if (scrollStatus.value === 1) {
    targetScrollTop = getPageScrollHeight() * 0.5
  } else if (scrollStatus.value === 2) {
    targetScrollTop = getPageScrollHeight()
  }

  // 执行平滑滚动
  window.scrollTo({
    top: targetScrollTop,
    behavior: 'smooth'
  })
}

onMounted(() => {
  window.addEventListener('keydown', handleKeydown)
})

onUnmounted(() => {
  window.removeEventListener('keydown', handleKeydown)
})
</script>

补充说明

  • 如果需要在指定容器内滚动而非整个页面,把window.scrollTo替换为对应容器DOM元素的scrollTo方法即可
  • 页面高度动态变化的场景下,每次滚动前重新计算页面总高度即可适配
  • 可自行调整分段数量和每个分段的滚动占比,只需要修改状态枚举值和对应目标位置的计算逻辑
  • Vue2项目可直接复用逻辑,把组合式API替换为选项式API的data、mounted、beforeDestroy生命周期即可

内容的提问来源于stack exchange,提问作者TKO

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 20:15:05