vue可拖动float元素

浮动div实现全屏可拖动功能

定时器控制长按时间,超过100毫秒开始进行拖拽

<template>
    <div class="floatBtn"
        :class="[{moveBtn: longClick}, `${btnType}Btn`]"
        @touchstart="touchstart($event)"
        @touchmove="touchMove($event)"
        @touchend="touchEnd($event)">
        <span>拖动按钮</span>
    </div>
</template>
<script>
export default {
    data() {
        return {
            timeOutEvent: 0,
            longClick: 0,
            // 手指原始位置
            oldMousePos: {},
            // 元素原始位置
            oldNodePos: {},
            btnType: 'right'
        };
    },

    methods:{
        clickBtn(){
            this.$emit('fatherMethod');
        },
        touchstart(ev) {
            // 定时器控制长按时间,超过100毫秒开始进行拖拽
            this.timeOutEvent = setTimeout(() => {
                this.longClick = 1;
            }, 100);
            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) {
            // 未达到100毫秒就移动则不触发长按,清空定时器
            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% - 55px)' : 0;
                this.btnType = 
                    (offsetLeft + 50) > (clientWidth / 2) ? 
                    'right' : 'left';
            }
        },
    }
};
</script>

<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: 55px;
    left: calc(100% - 55px);
    top: calc(100% - 200px);
    color: #fff;
    background: #ffb300;
    font-size: 12px;
    height: 55px;
    text-align: center;
    box-sizing: border-box;
    display: flex;
    justify-content: center;
    align-items: center;
    border-radius: 50%;
    filter: drop-shadow(2px 4px 8px #bab8b4);
  }
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值