实现屏幕右侧可拖动的悬浮按钮
在现代的前端开发中,悬浮按钮广泛应用于各种场景。本文将介绍如何在 Vue 2 项目中实现一个固定在屏幕右侧、可垂直拖动的悬浮按钮。按钮拖动后会自动固定在屏幕的右侧,避免按钮超出屏幕范围,并配合抽屉组件实现快捷菜单功能。
功能需求
固定在屏幕右侧:按钮始终固定在屏幕的右侧,用户无法水平拖动按钮。垂直拖动:用户可以自由拖动按钮在垂直方向上移动,并限制在屏幕上下边界内。贴边显示:拖动结束后,按钮始终保持贴边显示。抽屉菜单:点击按钮可打开抽屉,展示快捷菜单功能。实现步骤
1. 创建悬浮按钮组件
首先,创建一个 Vue 组件用于实现悬浮按钮和抽屉功能。我们使用 element-ui
组件库来实现按钮和抽屉,并添加拖动和贴边逻辑。
<template> <div v-if="shouldShowButton"> <!-- 小箭头按钮,控制悬浮按钮的显示和隐藏 --> <div v-if="!floatingButtonVisible" class="arrow-button" @click="toggleFloatingButton" > → </div> <!-- 悬浮按钮 --> <transition name="slide-fade"> <el-button v-if="floatingButtonVisible" class="floating-button" type="primary" circle @mousedown="startDrag" @click="toggleDrawer" :style="{ top: `${buttonPosition.y}px`, right: `20px`, transition: isDragging ? 'none' : 'top 0.3s ease, right 0.3s ease' }" > {{ todoCount }} </el-button> </transition> <!-- 抽屉 --> <el-drawer v-model="drawerVisible" direction="rtl" size="50%" title="快捷菜单" @close="toggleDrawer" > <!-- 抽屉内容 --> <el-tabs type="border-card" style="min-height: 500px"> <el-tab-pane label="我的待办" style="height:500px;overflow: auto;"> <!-- 演示表格 --> <el-table :cell-style="{'text-align':'center'}" :data="demoData" :header-cell-style="{'text-align':'center'}" border table-layout="auto" class="table-style" highlight-current-row > <el-table-column label="示例列1" prop="column1"></el-table-column> <el-table-column label="示例列2" prop="column2"></el-table-column> </el-table> </el-tab-pane> <el-tab-pane label="已办" style="height:700px;overflow: auto;"> <!-- 演示表格 --> <el-table :cell-style="{'text-align':'center'}" :data="demoData" :header-cell-style="{'text-align':'center'}" border table-layout="auto" highlight-current-row class="table-style" > <el-table-column label="示例列1" prop="column1"></el-table-column> <el-table-column label="示例列2" prop="column2"></el-table-column> </el-table> </el-tab-pane> </el-tabs> </el-drawer> </div></template><script>export default { data() { return { drawerVisible: false, floatingButtonVisible: true, todoCount: 5, // 代办事项数量 isDragging: false, buttonPosition: { y: window.innerHeight - 70 }, // 初始位置:右下角 startY: 0, demoData: [ { column1: "示例数据1", column2: "示例数据2" }, { column1: "示例数据3", column2: "示例数据4" }, ], // 演示数据 }; }, computed: { shouldShowButton() { return !this.$route.path.includes("/login"); }, }, mounted() { // 监听窗口大小变化 window.addEventListener("resize", this.updateButtonPosition); }, beforeDestroy() { // 在组件销毁时移除监听器 window.removeEventListener("resize", this.updateButtonPosition); }, methods: { toggleDrawer() { this.drawerVisible = !this.drawerVisible; }, toggleFloatingButton() { this.floatingButtonVisible = !this.floatingButtonVisible; }, startDrag(event) { this.isDragging = true; this.startY = event.clientY - this.buttonPosition.y; document.addEventListener("mousemove", this.onDrag); document.addEventListener("mouseup", this.stopDrag); }, onDrag(event) { if (this.isDragging) { // 只允许垂直移动,限制范围在屏幕内 let newY = event.clientY - this.startY; newY = Math.max(0, Math.min(newY, window.innerHeight - 50)); this.buttonPosition.y = newY; } }, stopDrag() { this.isDragging = false; document.removeEventListener("mousemove", this.onDrag); document.removeEventListener("mouseup", this.stopDrag); }, updateButtonPosition() { // 当窗口调整大小时更新按钮位置,确保按钮不超出屏幕 this.buttonPosition.y = Math.min(this.buttonPosition.y, window.innerHeight - 50); }, },};</script><style scoped>.floating-button { position: fixed; z-index: 1000; display: flex; justify-content: center; align-items: center; width: 50px; height: 50px; border-radius: 50%; transition: top 0.3s ease, right 0.3s ease; cursor: pointer; right: 20px; /* 固定在右侧 */}.arrow-button { position: fixed; right: 0; bottom: 20px; z-index: 1000; width: 20px; height: 50px; background-color: #409eff; color: white; display: flex; justify-content: center; align-items: center; border-radius: 0 10px 10px 0; cursor: pointer;}.slide-fade-enter-active,.slide-fade-leave-active { transition: all 0.3s ease;}.slide-fade-enter,.slide-fade-leave-to { transform: translateX(100%); opacity: 0;}</style>
2. 实现逻辑说明
固定右侧贴边: 悬浮按钮始终固定在屏幕右侧(通过 right: 20px;
),用户无法水平拖动按钮,仅能在垂直方向上移动。
垂直移动: 在 onDrag
方法中,仅允许按钮在 y
轴上移动。通过限制 y
值,确保按钮不会超出屏幕上下边界。
贴边显示: 由于按钮始终固定在右侧,因此在用户停止拖动时按钮自动贴边。
抽屉菜单: 按钮的点击事件触发抽屉菜单的显示或隐藏,并展示了一些演示数据。
窗口大小调整: 在窗口大小发生变化时,通过 updateButtonPosition
方法动态调整按钮位置,确保按钮不会超出屏幕。
3. 总结
通过上述代码和实现逻辑,我们成功创建了一个固定在屏幕右侧且可垂直拖动的悬浮按钮。这个按钮在移动后始终贴边,并且结合抽屉组件实现了快捷菜单功能。在实际应用中,你可以根据项目需求进一步定制和扩展此功能。
希望这篇博客内容能够帮助你理解和实现类似的悬浮按钮功能。如有任何疑问或建议,欢迎在评论区留言讨论!