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

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

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

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

(0)

相关推荐

  • Vue实现开关按钮拖拽效果

    本文实例为大家分享了Vue实现开关按钮拖拽效果的具体代码,供大家参考,具体内容如下 css: <style> .box { position: absolute; left: 100px; top: 100px; width: 100px; height: 100px; background: red; } .box2 { position: absolute; left: 400px; top: 100px; width: 100px; height: 100px; background:

  • vue悬浮可拖拽悬浮按钮的实例代码

    前言 vue开发手机端悬浮按钮实现,可以拖拽,滚动的时候收到里边,不影响视线 github地址 使用,基于vue-cli3.0+webpack 4+vant ui + sass+ rem适配方案+axios封装,构建手机端模板脚手架 vue-h5-template 后续将发布各种商城组件组件,让商城简单高效开发 线上体验 使用 将 src/components文件夹下的s-icons组件放到你的组件目录下 使用组件 // template <template> <div> <

  • vue实现可移动的悬浮按钮

    本文实例为大家分享了vue实现可随处移动悬浮按钮的具体代码,供大家参考,具体内容如下 1.html代码 <div class="callback float" @click="onClick" @mousedown="down" @touchstart="down" @mousemove="move" @touchmove="move" @mouseup="end&quo

  • vue实现移动端的开关按钮

    本文实例为大家分享了vue实现移动端的开关按钮的具体代码,供大家参考,具体内容如下 逻辑: 1.写一个椭圆形的div 2.动态改变这个椭圆形的div的背景颜色 3.写一个圆点,这个圆点采用绝对定位的方式,定位在椭圆形的div上 4.开关来回切换的时候,要使用translateX移动圆点的位置,并且动态改变椭圆形 div的背景颜色 代码: html: <!--部门功能-->         <div class="department">             

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

    目录 功能介绍: 大致需求: 整体思路: 具体实现: 一.position:fixed布局: 二.touch事件绑定: 三.页面引入: 本文实例为大家分享了vue实现移动端拖拽悬浮按钮的具体代码,供大家参考,具体内容如下 功能介绍: 在移动端开发中,实现悬浮按钮在侧边显示,为不遮挡页面内容,允许手指拖拽换位. 大致需求: 1.按钮在页面侧边悬浮显示:2.手指长按按钮,按钮改变样式,允许拖拽改变位置:3.按钮移动结束,手指松开,计算距离左右两侧距离并自动移动至侧边显示:4.移动至侧边后,按钮根据具

  • Vue实现移动端拖拽交换位置

    本文实例为大家分享了Vue实现移动端拖拽交换位置的具体代码,供大家参考,具体内容如下 <template> <div class="imageUploaderPage"> <ul ref='imgList' class="imgList"> <li ref='imgItem' class="imgCoverItem" v-for='(item, index) in filesResults' :key='

  • vue基于Echarts的拖拽数据可视化功能实现

    背景 我司产品提出了一个需求,做一个数据基于Echars的可拖拽缩放的数据可视化,上网百度了一番,结果出现了两种结局,一种花钱买成熟产品(公司不出钱),一种没有成熟代码,只能自己写了,故事即将开始,敬请期待.......  不,还是先上一张效果图吧,请看...... 前期知识点 1. offset(偏移量) 定义:当前元素在屏幕上占用的空间,如下图: 其中: offsetHeight: 该元素在垂直方向上的占用的空间,单位为px,不包括margin. offsetWidth:该元素在水平方向上的

  • vue实现放大缩小拖拽功能

    本文实例为大家分享了vue实现放大缩小拖拽功能的具体代码,供大家参考,具体内容如下 点击放大至全屏 再次点击缩小至原始  这个弹框是基于element dialog的基础上写的 1.再utils文件夹下面新建一个directives.js  (封装好了 直接拿去用) import Vue from 'vue'; import bigPic from '../assets/images/bigChange.png'; // v-dialogDrag: 弹窗拖拽属性 Vue.directive('d

  • vue draggable组件实现拖拽及点击无效问题的解决

    目录 一.效果图 二.拖拽及点击无效解决方法 三.vuedraggable的使用 在实现一个移动端项目的时候,根据产品需求,要实现一个既能增加删除又可以拖拽调换位置的效果,然后我使用了draggable组件,然后发现放到手机上的时候苹果(ios)手机可以正常使用,但是鸿蒙系统的手机(例如华为pro40)有些是不可以正常拖拽.增加和删除,只能一开始正常操作两三个,然后后面就怎么点都没有什么反应.通过多次尝试和查找方法,最终找到了解决办法,我在这里总结一下. 一.效果图 二.拖拽及点击无效解决方法

  • jQuery 移动端拖拽(模块化开发,触摸事件,webpack)

    通过jquery可以很容易实现CP端的拖拽.但是在移动端却不好用了.于是我自己写了一个在移动端的拖拽demo,主要用到的事件是触摸事件(touchstart,touchmove和touchend). 这个demo实现的功能是:可以拖拽的元素(在这里是图片)位于列表中,这些元素可以被拖到指定区域,到达指定区域(控制台)后,元素被插入控制台后,原来的拖动元素返回原位置,新的元素依然可以在控制台中拖动,也能拖出控制台. 在这个demo中一个用三个模块,分别为ajax模块,drag模块,position

  • vue插件draggable实现拖拽移动图片顺序

    本文实例为大家分享了vue插件draggable实现拖拽移动图片顺序的具体方法,供大家参考,具体内容如下 例如图片显示的这种图片列表.商品展示需要拖动图片改变顺序,vuedraggable可以实现拖拽. 首先, npm i vuedraggable 然后在组件中引入, import draggable from 'vuedraggable'; 定义组件, components: { draggable, }, 标签中应用, <ul class="pic-list clearfix"

  • vue.draggable实现表格拖拽排序效果

    本文实例为大家分享了vue.draggable实现表格拖拽排序效果展示的具体代码,供大家参考,具体内容如下 主要使用vuedraggable和sortablejs两个组件. 1.安装组件 npm install vuedraggable npm install sortablejs 2.引入组件 import draggable from 'vuedraggable'; import Sortable from 'sortablejs'; export default { components:

  • vue element el-transfer增加拖拽功能

    芯资管项目要求el-transfer增加拖拽排序,左右上下互相拖拽功能: 原来的组件不支持拖拽,这里要用个第三方脱宅组件sortablejs 首先安装 sudo npm i sortablejs --save-dev html代码 <template> <el-transfer ref="transfer" id="transfer" v-model="value" :data="data"> <

随机推荐