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

之前写过拖动滑块验证

但是发现移动端拖不动了

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
<!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>

大功告成!

touchmove