vue实现移动端拖拽悬浮按钮

 更新时间:2022年07月14日 10:40:28   作者:iatkotworld  
这篇文章主要为大家详细介绍了vue实现移动端拖拽悬浮按钮,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

本文实例为大家分享了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>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持程序员之家。

相关文章

  • vue货币过滤器的实现方法

    vue货币过滤器的实现方法

    这篇文章主要为大家详细介绍了vue货币过滤器的实现方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-04-04
  • vue 集成 vis-network 实现网络拓扑图的方法

    vue 集成 vis-network 实现网络拓扑图的方法

    这篇文章主要介绍了vue 集成 vis-network 实现网络拓扑图的方法,本文通过实例代码给大家介绍的非常详细 ,需要的朋友可以参考下
    2019-08-08
  • Vue?FileManagerPlugin?报错问题及解决

    Vue?FileManagerPlugin?报错问题及解决

    这篇文章主要介绍了Vue?FileManagerPlugin?报错问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • vue下拉列表的两种实现方式比较

    vue下拉列表的两种实现方式比较

    这篇文章主要介绍了vue下拉列表的两种实现方式比较,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • vue-cropper插件实现图片截取上传组件封装

    vue-cropper插件实现图片截取上传组件封装

    这篇文章主要为大家详细介绍了vue-cropper插件实现图片截取上传组件封装,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-05-05
  • 详解vue.js移动端配置flexible.js及注意事项

    详解vue.js移动端配置flexible.js及注意事项

    最近在用vue做移动端项目,网上找了一些移动端适配的方案,个人觉得手淘团队flexible.js还是比较容易上手,在这里做下总结。对vue.js移动端配置flexible.js 相关知识感兴趣的朋友跟随小编一起看看吧
    2019-04-04
  • vue-infinite-loading2.0 中文文档详解

    vue-infinite-loading2.0 中文文档详解

    本篇文章主要介绍了vue-infinite-loading2.0 中文文档详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-04-04
  • Vue3中的Refs和Ref详情

    Vue3中的Refs和Ref详情

    这篇文章主要介绍了Vue3中的Refs和Ref,文章围绕Vue3中的Refs和Ref得相关资料应用举例烦人方式展开详细内容,需要的朋友可以参考一下
    2021-11-11
  • vue后台管理之动态加载路由的方法

    vue后台管理之动态加载路由的方法

    这篇文章主要介绍了vue后台管理之动态加载路由的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • vue中使用axios请求post接口发送两次

    vue中使用axios请求post接口发送两次

    这篇文章主要为大家介绍了vue中使用axios请求post接口,请求会发送两次原因解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11

最新评论

?


http://www.vxiaotou.com