不爱贞子爱爽子
バキューン
<script setup>
import { reactive, ref, onMounted, onUnmounted, nextTick } from 'vue';
const dragData = reactive({
    beginClientX: 0,           /*距离屏幕左端距离*/
    mouseMoveStata: false,     /*触发拖动状态  判断*/
    maxwidth: '',               /*拖动最大宽度,依据滑块宽度算出来的*/
    confirmSuccess: false /*验证成功判断*/,
    message: '请按住滑块,拖动到最右边',
})
const dragDivRef = ref(null)
const moveDivRef = ref(null)

/** 
 * 拖动验证部分
 */

const initBar = () => {
    nextTick(() => {
        // 根据滑块宽度计算可拖动最大宽度
        dragData.maxwidth = dragDivRef.value.clientWidth - moveDivRef.value.clientWidth;
        // 监听手指的触摸事件
        document.addEventListener('mousemove', mouseMoveFn);
        // 监听手指离开事件
        document.addEventListener('mouseup', moseUpFn)
    })
}
const mousedownFn = (e) => {
    if (!dragData.confirmSuccess) {
        e.preventDefault && e.preventDefault();   //阻止文字选中等 浏览器默认事件
        dragData.mouseMoveStata = true;
        dragData.beginClientX = e.clientX;

    }
}
const mouseMoveFn = (e) => {
    if (dragData.mouseMoveStata) {
        let width = e.clientX - dragData.beginClientX;
        if (width > 0 && width <= dragData.maxwidth) {
            document.getElementsByClassName('moveDivBar')[0].style.left = width + 'px';
            document.getElementById('moveBgInfo').style.width = width + 'px';
        } else if (width > dragData.maxwidth) {
            document.getElementsByClassName('moveDivBar')[0].style.left = dragData.maxwidth + 'px';
            document.getElementById('moveBgInfo').style.width = dragData.maxwidth + 'px';
            dragData.mouseMoveStata = false
            dragData.confirmSuccess = true
            dragData.message = '验证通过'
        }
    }
}


const moseUpFn = (e) => {
    dragData.mouseMoveStata = false;
    if (!dragData.confirmSuccess) {
        var width = e.clientX - dragData.beginClientX;
        if (width < dragData.maxwidth) {
            document.getElementsByClassName('moveDivBar')[0].style.left = 0 + 'px';
            document.getElementById('moveBgInfo').style.width = 0 + 'px';
            dragData.confirmSuccess = false
        }
    }

};

onMounted(() => {
    initBar()
})

onUnmounted(() => {
    // 销毁监听移动
    document.removeEventListener('mousemove', mouseMoveFn);
    // 销毁监听手指离开事件
    document.removeEventListener('mouseup', moseUpFn)
})

/** 
 * 拖动验证部分
 */
</script>
<template>
    <div style="width: 400px;height: 38px; border: 1px solid #CED4DA;border-radius: 0.25rem; position: relative; text-align: center; line-height: 38px;user-select: none;"
        ref="dragDivRef">
        <div @mousedown="mousedownFn($event)" class="moveDivBar d-flex align-items-center justify-content-center"
            style="height: 36px;
                                                     background-color: #cfd4d9; 
                                                     width: 62px; position: absolute;left:0; cursor: move; border-radius:0 0.19rem 0.19rem 0 ;z-index: 2;" ref="moveDivRef">
            <i style="font-size: 20px;" class="ri-arrow-right-s-line"></i>
            <i style="font-size: 20px; margin-left: -10px;" class="ri-arrow-right-s-line"></i>
        </div>
        <div v-if="!dragData.mouseMoveStata"
            style="color: #888a98;position: absolute;text-align: center;margin: 0 auto; width: 100%; z-index: 1;">
            {{ dragData.message }}</div>
        <div v-if="dragData.mouseMoveStata"
            style="color: white;position: absolute;text-align: center;margin: 0 auto; width: 100%; z-index: 1;">
            {{ dragData.message }}</div>
        <div v-if="dragData.confirmSuccess"
            style="color: white;position: absolute;text-align: center;margin: 0 auto; width: 100%; z-index: 1;">
            {{ dragData.message }}</div>
        <div id="moveBgInfo"
            style="position: absolute; background-color: #51b09d;height: 36px; left: 0; top: 0;border-radius:0.19rem 0 0 0.19rem">
        </div>
    </div>
</template>

 图标需要自行替换

 

posted on 2024-08-26 17:16  不爱贞子爱爽子  阅读(7)  评论(0编辑  收藏  举报

! !