好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

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>

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

查看更多关于vue实现移动端拖拽悬浮按钮的详细内容...

  阅读:60次