zl程序教程

您现在的位置是:首页 >  其他

当前栏目

移动端拖动滑块验证

2023-02-25 18:19:53 时间

夫唯不争,故天下莫能与之争——老子

之前写过拖动滑块验证

但是发现移动端拖不动了

因为移动端使用的是touch事件:https://developer.mozilla.org/zh-CN/docs/Web/API/TouchEvent

我们对其进行改造,通过获取其第一个触控点的坐标进行计算

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>drag</title>
    <style>
        /* 外部放置滑动区域 */
        .container {
            width: 100%;
            height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        /* 滑动区域 */
        .drag-verify-band {
            background: #f4f7f8;
            width: 300px;
            height: 40px;
            border-radius: 12px;
            position: relative;
            box-shadow: 0 10px 20px -10px #ccc;
            transform: translateY(-3px);
        }

        /* 滑块 */
        .verify-btn {
            transition: background-color 0.2s;
            user-select: none;
            cursor: all-scroll;
            background-color: #1a5cff;
            color: #fff;
            border-radius: 12px;
            height: 100%;
            display: flex;
            align-items: center;
            justify-content: center;
            position: absolute;
            font-size: 12px;
        }

        /* 滑块内容文本 */
        .verify-btn-text {
            margin: 0 10px;
            white-space: nowrap;
        }
    </style>
</head>

<body>
    <div class="container">
        <!-- 滑动区域 -->
        <div class="drag-verify-band">
            <!-- 滑块 -->
            <div class="verify-btn">
                <!-- 滑块内文本 -->
                <div class="verify-btn-text">向右滑动解锁?</div>
            </div>
        </div>
    </div>
    <script>
        // 获取可滑动区域
        const verifyBand = document.querySelector(".drag-verify-band")
        // 获取滑块区域宽度、偏移位置
        const { offsetWidth: bandWidth, offsetLeft: bandLeft } = verifyBand
        // 获取滑块
        const verifyBtn = document.querySelector(".verify-btn");
        // 获取滑块宽度
        const { offsetWidth: btnWidtn } = verifyBtn
        // 给滑块绑定鼠标按下事件
        function mousedown(btnMouseDownEvent) {

            // 获取当前鼠标点击时相对于父节点x坐标,点击滑块越右,偏移量越大
            let { changedTouches: [touch] = [{}] } = btnMouseDownEvent
            let { layerX: mouseOffsetX = touch.clientX - touch.target.getBoundingClientRect().left } = btnMouseDownEvent
            // console.log({ mouseOffsetX });

            // 定义是否滑动到最右的标识
            let isMostRight = false
            // 定义移动函数
            function mousemove(e) {

                // 获取当前鼠标移动时,相对于视窗最左侧的x坐标
                const { changedTouches: [touch] = [{}], clientX = touch.clientX } = e

                // 鼠标相对视窗最左侧的x坐标,需要减去 滑块外部滑动区域的x坐标,再减去 鼠标按下的x偏移量,得到当前需要移动的距离
                let safeX = clientX - bandLeft - mouseOffsetX
                // 移动距离不能小于0(不能超出最左边)
                safeX = Math.max(safeX, 0)
                // 移动距离不能大于 滑块的宽度减去按钮的宽度(不能超出最右边)
                const maxOffsetX = bandWidth - btnWidtn
                safeX = Math.min(safeX, maxOffsetX);
                // 记录一下是否滑动到了最右边
                isMostRight = safeX === maxOffsetX
                // 日志一下
                // console.log({ safeX });
                // 将滑块样式的left设置为当前移动的距离
                verifyBtn.style.left = `${safeX}px`;
            }

            // 抬起鼠标事件
            function mouseup(e) {
                // 判断当前滑块是否滑到最右边
                console.log({ isMostRight });
                if (isMostRight) {
                    // 成功验证逻辑
                    // 此处可以改为你自定义逻辑
                    console.log('验证成功');
                    // 这里首先替换了按钮内的文本
                    verifyBtn.innerHTML = `<div class="verify-btn-text">验证成功☕</div>`
                    // 将坐标位置设为最右边
                    verifyBtn.style.left = 'initial';
                    verifyBtn.style.right = 0;
                    // 按钮背景颜色更改
                    verifyBtn.style.backgroundColor = '#46c93a';

                    // 2s后重置一下
                    setTimeout(() => {
                        verifyBtn.innerHTML = `<div class="verify-btn-text">向右滑动解锁?</div>`
                        verifyBtn.style.backgroundColor = '#1a5cff';
                        verifyBtn.style.right = 'initial';
                        verifyBtn.style.left = 0
                    }, 2000)
                } else {
                    // 失败逻辑,重置滑块位置
                    verifyBtn.style.left = 0;
                }

                // 销毁事件监听
                document.removeEventListener('mousemove', mousemove);
                document.removeEventListener('touchmove', mousemove);
                document.removeEventListener('mouseup', mouseup);
                document.removeEventListener('touchend', mouseup);
            }

            // 给全局dom节点绑定鼠标移动事件
            document.addEventListener('mousemove', mousemove)
            document.addEventListener('touchmove', mousemove)
            // 给全局dom节点绑定鼠标抬起事件
            document.addEventListener('mouseup', mouseup)
            document.addEventListener('touchend', mouseup)
        }
        verifyBtn.addEventListener('mousedown', mousedown)
        verifyBtn.addEventListener('touchstart', mousedown)
    </script>
</body>

</html>

大功告成!