# 滑块验证前端实现
# 前言
ps:只是前端验证 不具备高安全性;
实现:监听滑块的移动事件,获取它离左侧的距离,赋值给分离出来的验证模块就可以了,至于陷下去的模块,得到图片的大小,根据图片的长宽的一半随机赋值吧(因为这个模块一般都在右侧靠中间的位置)
# 源码
html
<div class="box">
<div class="imgBox">
<div class="verify"></div>
<div class="verified"></div>
</div>
<div class="handle">
<span class="swiper"></span>
<span class="text">拖动滑块</span>
</div>
<div class="refreshBox">
<span class="refresh">点击切换图片</span>
</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
css
.box {
width: 300px;
padding: 20px;
background-color: #fff;
box-shadow: 2px 2px 8px 0 rgba(0, 0, 0, 0.4);
}
.imgBox {
position: relative;
width: 300px;
overflow: hidden;
box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.4);
}
.imgBox img {
width: 100%;
height: 250px;
}
.imgBox div {
display: none;
}
.handle {
display: flex;
align-items: center;
position: relative;
height: 30px;
border-radius: 20px;
margin: 20px 0;
padding: 4px 0 4px 70px;
box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2) inset;
background: #f5f5f5;
user-select: none;
}
.text {
opacity: 1;
transition: opacity 0.5s ease-in-out;
color: #aaa;
}
.swiper {
position: absolute;
top: -10px;
left: 0px;
width: 58px;
height: 58px;
border-radius: 50%;
background-color: pink;
box-shadow: 2px 2px 6px 0 rgba(0, 0, 0, 0.2);
}
.verify {
position: absolute;
left: 10px;
width: 38px;
height: 38px;
border-radius: 5px;
background-repeat: no-repeat;
background-attachment: scroll;
background-size: 300px;
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.4), 0 0 10px 0 rgba(90, 90, 90, 0.4);
z-index: 10;
}
.verified {
position: absolute;
width: 38px;
height: 38px;
border-radius: 5px;
background-color: rgba(0, 0, 0, 0.1);
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.4) inset;
}
.refreshBox {
border-top: 1px solid #ccc;
padding: 15px 0 0 5px;
}
.refresh {
color: #fff;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
padding: 8px 20px;
border-radius: 20px;
background-color: #555;
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.4);
transition: all 0.5s ease-in-out;
}
.refresh.click {
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.4) inset;
}
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
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
js
var box = $('.box'),
imgBox = $('.imgBox'),
handle = $('.handle'),
swiper = $('.swiper'),
text = $('.text'),
verify = $('.verify'),
verified = $('.verified'),
refresh = $('.refresh')
// 图片集合
var imgs = []
for (let i = 1; i < 17; i++) {
imgs.push('' + i + i)
}
$(function() {
// 随机添加背景图
refreshImg()
refresh.click(function() {
e = event || window.event
e.stopPropagation()
refreshImg()
start()
})
refresh.mousedown(function() {
$(this).addClass('click')
})
refresh.mouseup(function() {
$(this).removeClass('click')
})
window.onload = start()
})
function start() {
var verImg = document.getElementsByClassName('verImg')[0]
if (verImg) {
verImg.onload = function() {
// 获取图片高度
var imgH = this.clientHeight
// 随机生成坐标(图片框固定宽度为300px,高度不定)
var verX = 150 * (1 + Math.random()) - 38,
verY = imgH / 4 + Math.random() * imgH / 2
// 用户移动滑块函数
fnDown(verX, verY)
}
}
}
function fnDown(verX, verY) {
swiper.mousedown(function() {
e = event || window.event
e.stopPropagation()
// 30为模块宽度
verify.css({
display: 'block',
top: `${verY}px`,
'background-position': `-${verX}px -${verY}px`
})
verified.css({ display: 'block', left: `${verX}px`, top: `${verY}px` })
// 获取鼠标到按钮的距离
var disX = e.clientX - $(this).offset().left,
disY = e.clientY - $(this).offset().top
text.css('opacity', '0')
// 防止重复绑定触发多次
box.unbind('mousemove')
box.unbind('mouseup')
// 移动
box.bind('mousemove', function() {
e = event || window.event
fnMove(e, disX, disY)
})
// 释放
box.bind('mouseup', function() {
var stopL = verify.offset().left - 28
// 误差在2px以内则算做成功
if (Math.abs(stopL - verX) > 2) {
alert('验证失败')
} else {
alert('验证成功')
}
// 解除绑定,并将滑动模块归位
box.unbind('mousemove')
swiper.css('left', '0px')
verify.css('left', '10px')
text.css('opacity', '1')
box.unbind('mouseup')
})
})
}
function fnMove(e, posX, posY) {
// 这里的e是以鼠标为参考
var l = e.clientX - posX - $(handle).offset().left,
winW = $(handle).width() + 29
// 限制拖动范围只能在handle中
if (l < 0) {
l = 0
} else if (l > winW) {
l = winW
}
swiper.css('left', `${l}px`)
verify.css('left', `${l + 10}px`)
}
function refreshImg() {
// 随机生成下标
var index = Math.round(Math.random() * 15)
var imgH = 0
verify.hide()
verified.hide()
var verImg = $('.verImg')
if (verImg.length) {
verImg.attr('src', `imgs/${imgs[index]}.jpg`) //imgs文件夹存放图片
} else {
imgBox.prepend(`<img class='verImg' src="imgs/${imgs[index]}.jpg" />`)
}
verify.css('background-image', `url('imgs/${imgs[index]}.jpg')`)
}
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
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
最主要的三部分有了,还要
自己需要建一个文件夹存放图片,从中随机获取图片
我自己是imgs文件夹;