实现屏幕右侧可拖动的悬浮按钮
在现代的前端开发中,悬浮按钮广泛应用于各种场景。本文将介绍如何在 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. 总结
通过上述代码和实现逻辑,我们成功创建了一个固定在屏幕右侧且可垂直拖动的悬浮按钮。这个按钮在移动后始终贴边,并且结合抽屉组件实现了快捷菜单功能。在实际应用中,你可以根据项目需求进一步定制和扩展此功能。
希望这篇博客内容能够帮助你理解和实现类似的悬浮按钮功能。如有任何疑问或建议,欢迎在评论区留言讨论!
版权归原作者 饼干饿死了 所有, 如有侵权,请联系我们删除。