如何用Vue实现移动端悬浮拖拽按钮功能?

2026-03-31 17:391阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1030个文字,预计阅读时间需要5分钟。

如何用Vue实现移动端悬浮拖拽按钮功能?

目录+功能介绍+基本需求+整体思路+具体实现+一、position:fixed布局+二、touch事件绑定+三、页面引入+文本实例:大家分享了vue实现移动端拖拽悬浮按钮的具体代码,供大家参考。

目录
  • 功能介绍:
  • 大致需求:
  • 整体思路:
  • 具体实现:
    • 一、position:fixed布局:
    • 二、touch事件绑定:
    • 三、页面引入:

本文实例为大家分享了vue实现移动端拖拽悬浮按钮的具体代码,供大家参考,具体内容如下

功能介绍:

在移动端开发中,实现悬浮按钮在侧边显示,为不遮挡页面内容,允许手指拖拽换位。

如何用Vue实现移动端悬浮拖拽按钮功能?

大致需求:

1、按钮在页面侧边悬浮显示;
2、手指长按按钮,按钮改变样式,允许拖拽改变位置;
3、按钮移动结束,手指松开,计算距离左右两侧距离并自动移动至侧边显示;
4、移动至侧边后,按钮根据具体左右两次位置判断改变现实样式;

整体思路:

1、按钮实行position:fixed布局,在页面两侧最上层悬浮显示;
2、手指长按可使用定时器来判断,若手指松开,则关闭定时器,等待下次操作再启用;
3、跟随手指移动计算按钮与页面两侧的距离,判断手指松开时停留的位置;

简单效果展示:

具体实现:

一、position:fixed布局:

使用定位实现

<!-- 外层ul控制卡片范围 --> <div>     <div class="floatBtn"          :class="[{moveBtn: longClick}, `${btnType}Btn`]">     <span>悬浮按钮</span>   </div> </div>

<style lang="scss" scoped>   @mixin notSelect{     -moz-user-select:none; /*火狐*/     -webkit-user-select:none; /*webkit浏览器*/     -ms-user-select:none; /*IE10*/     -khtml-user-select:none; /*早期浏览器*/     user-select:none;   }   @mixin not-touch {     -webkit-touch-callout: none;     -webkit-user-select: none;     -khtml-user-select: none;     -moz-user-select: none;     -ms-user-select: none;     user-select: none;   }   .floatBtn {     @include notSelect;     @include not-touch();     position: fixed;     z-index: 1;     overflow: hidden;     width: 100px;     left: calc(100% - 100px);     top: calc(100% - 100px);     color: #E0933A;     background: #FCEBD0;     font-size: 14px;     height: 36px;     line-height: 36px;     text-align: center;     box-sizing: border-box;     display: flex;     justify-content: center;     align-items: center;     padding: 10px;     &.rightBtn {       border-radius: 20px 0 0 20px;     }     &.leftBtn {       border-radius: 0 20px 20px 0;     }     &.moveBtn {       border-radius: 20px;     }   } </style>

二、touch事件绑定:

应用到touchstart,touchmove,touchend事件,使用定时器实现长按效果:

<div class="floatBtn"     :class="[{moveBtn: longClick}, `${btnType}Btn`]"     @touchstart="touchstart($event)"     @touchmove="touchMove($event)"     @touchend="touchEnd($event)" >     <span>悬浮按钮</span> </div>

<script> export default {     data() {         return {             timeOutEvent: 0,             longClick: 0,             // 手指原始位置             oldMousePos: {},             // 元素原始位置             oldNodePos: {},             btnType: 'right'         };     },     touchstart(ev) {         // 定时器控制长按时间,超过500毫秒开始进行拖拽         this.timeOutEvent = setTimeout(() => {             this.longClick = 1;         }, 500);         const selectDom = ev.currentTarget;         const { pageX, pageY } = ev.touches[0]; // 手指位置         const { offsetLeft, offsetTop } = selectDom; // 元素位置         // 手指原始位置         this.oldMousePos = {             x: pageX,             y: pageY         };         // 元素原始位置         this.oldNodePos = {             x: offsetLeft,             y: offsetTop         };         selectDom.style.left = `${offsetLeft}px`;         selectDom.style.top = `${offsetTop}px`;     },     touchMove(ev) {         // 未达到500毫秒就移动则不触发长按,清空定时器         clearTimeout(this.timeOutEvent);         if (this.longClick === 1) {             const selectDom = ev.currentTarget;             // x轴偏移量             const lefts = this.oldMousePos.x - this.oldNodePos.x;             // y轴偏移量             const tops = this.oldMousePos.y - this.oldNodePos.y;             const { pageX, pageY } = ev.touches[0]; // 手指位置             selectDom.style.left = `${pageX - lefts}px`;             selectDom.style.top = `${pageY - tops}px`;         }     },     touchEnd(ev) {         // 清空定时器         clearTimeout(this.timeOutEvent);         if (this.longClick === 1) {             this.longClick = 0;             const selectDom = ev.currentTarget;             const {clientWidth, clientHeight} = document.body;             const {offsetLeft, offsetTop} = selectDom;             selectDom.style.left =                  (offsetLeft + 50) > (clientWidth / 2) ?                  'calc(100% - 100px)' : 0;             if (offsetTop < 90) {                 selectDom.style.top = '90px';             } else if (offsetTop + 36 > clientHeight) {                 selectDom.style.top = `${clientHeight - 36}px`;             }             this.btnType =                  (offsetLeft + 50) > (clientWidth / 2) ?                  'right' : 'left';         }     }, }; </script>

三、页面引入:

单个页面引入

<template>     <floatBtn/> </template>

<script> import floatBtn from './floatBtn'; export default {     components: {         floatBtn     }, }; </script>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持易盾网络。

本文共计1030个文字,预计阅读时间需要5分钟。

如何用Vue实现移动端悬浮拖拽按钮功能?

目录+功能介绍+基本需求+整体思路+具体实现+一、position:fixed布局+二、touch事件绑定+三、页面引入+文本实例:大家分享了vue实现移动端拖拽悬浮按钮的具体代码,供大家参考。

目录
  • 功能介绍:
  • 大致需求:
  • 整体思路:
  • 具体实现:
    • 一、position:fixed布局:
    • 二、touch事件绑定:
    • 三、页面引入:

本文实例为大家分享了vue实现移动端拖拽悬浮按钮的具体代码,供大家参考,具体内容如下

功能介绍:

在移动端开发中,实现悬浮按钮在侧边显示,为不遮挡页面内容,允许手指拖拽换位。

如何用Vue实现移动端悬浮拖拽按钮功能?

大致需求:

1、按钮在页面侧边悬浮显示;
2、手指长按按钮,按钮改变样式,允许拖拽改变位置;
3、按钮移动结束,手指松开,计算距离左右两侧距离并自动移动至侧边显示;
4、移动至侧边后,按钮根据具体左右两次位置判断改变现实样式;

整体思路:

1、按钮实行position:fixed布局,在页面两侧最上层悬浮显示;
2、手指长按可使用定时器来判断,若手指松开,则关闭定时器,等待下次操作再启用;
3、跟随手指移动计算按钮与页面两侧的距离,判断手指松开时停留的位置;

简单效果展示:

具体实现:

一、position:fixed布局:

使用定位实现

<!-- 外层ul控制卡片范围 --> <div>     <div class="floatBtn"          :class="[{moveBtn: longClick}, `${btnType}Btn`]">     <span>悬浮按钮</span>   </div> </div>

<style lang="scss" scoped>   @mixin notSelect{     -moz-user-select:none; /*火狐*/     -webkit-user-select:none; /*webkit浏览器*/     -ms-user-select:none; /*IE10*/     -khtml-user-select:none; /*早期浏览器*/     user-select:none;   }   @mixin not-touch {     -webkit-touch-callout: none;     -webkit-user-select: none;     -khtml-user-select: none;     -moz-user-select: none;     -ms-user-select: none;     user-select: none;   }   .floatBtn {     @include notSelect;     @include not-touch();     position: fixed;     z-index: 1;     overflow: hidden;     width: 100px;     left: calc(100% - 100px);     top: calc(100% - 100px);     color: #E0933A;     background: #FCEBD0;     font-size: 14px;     height: 36px;     line-height: 36px;     text-align: center;     box-sizing: border-box;     display: flex;     justify-content: center;     align-items: center;     padding: 10px;     &.rightBtn {       border-radius: 20px 0 0 20px;     }     &.leftBtn {       border-radius: 0 20px 20px 0;     }     &.moveBtn {       border-radius: 20px;     }   } </style>

二、touch事件绑定:

应用到touchstart,touchmove,touchend事件,使用定时器实现长按效果:

<div class="floatBtn"     :class="[{moveBtn: longClick}, `${btnType}Btn`]"     @touchstart="touchstart($event)"     @touchmove="touchMove($event)"     @touchend="touchEnd($event)" >     <span>悬浮按钮</span> </div>

<script> export default {     data() {         return {             timeOutEvent: 0,             longClick: 0,             // 手指原始位置             oldMousePos: {},             // 元素原始位置             oldNodePos: {},             btnType: 'right'         };     },     touchstart(ev) {         // 定时器控制长按时间,超过500毫秒开始进行拖拽         this.timeOutEvent = setTimeout(() => {             this.longClick = 1;         }, 500);         const selectDom = ev.currentTarget;         const { pageX, pageY } = ev.touches[0]; // 手指位置         const { offsetLeft, offsetTop } = selectDom; // 元素位置         // 手指原始位置         this.oldMousePos = {             x: pageX,             y: pageY         };         // 元素原始位置         this.oldNodePos = {             x: offsetLeft,             y: offsetTop         };         selectDom.style.left = `${offsetLeft}px`;         selectDom.style.top = `${offsetTop}px`;     },     touchMove(ev) {         // 未达到500毫秒就移动则不触发长按,清空定时器         clearTimeout(this.timeOutEvent);         if (this.longClick === 1) {             const selectDom = ev.currentTarget;             // x轴偏移量             const lefts = this.oldMousePos.x - this.oldNodePos.x;             // y轴偏移量             const tops = this.oldMousePos.y - this.oldNodePos.y;             const { pageX, pageY } = ev.touches[0]; // 手指位置             selectDom.style.left = `${pageX - lefts}px`;             selectDom.style.top = `${pageY - tops}px`;         }     },     touchEnd(ev) {         // 清空定时器         clearTimeout(this.timeOutEvent);         if (this.longClick === 1) {             this.longClick = 0;             const selectDom = ev.currentTarget;             const {clientWidth, clientHeight} = document.body;             const {offsetLeft, offsetTop} = selectDom;             selectDom.style.left =                  (offsetLeft + 50) > (clientWidth / 2) ?                  'calc(100% - 100px)' : 0;             if (offsetTop < 90) {                 selectDom.style.top = '90px';             } else if (offsetTop + 36 > clientHeight) {                 selectDom.style.top = `${clientHeight - 36}px`;             }             this.btnType =                  (offsetLeft + 50) > (clientWidth / 2) ?                  'right' : 'left';         }     }, }; </script>

三、页面引入:

单个页面引入

<template>     <floatBtn/> </template>

<script> import floatBtn from './floatBtn'; export default {     components: {         floatBtn     }, }; </script>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持易盾网络。