es6 封装一个登录注册的验证滑块
1,需求分析
滑块从左滑到右,开始滑、结束滑两种状态。两种状态显示的内容和样式的不同。
这是淘宝注册验证滑块的示例图
2,代码分析
const render = Symbol('render') const event = Symbol('event') class Slider { constructor (options) { this.options = options if (!options.container) { throw new Error('slider需要一个提供一个容器配置') } this[render](options) this[event](options) } }
这里定义了一个Slider类,用symbol定义了render 渲染和event事件的初始化函数
在渲染函数中,我们需要将滑块的模板直接放到页面上,所以可以这样做:
[render] (options) { const unsuccessTip = options.unsuccessTip || '请拖动滑块到最右边' const template = ` <div class="sliderBox" id="box"> / <div class="slide-part" id="slide-part"></div> <div class="slide-btn" id="slide-btn">>></div> <span class="notice" id="notice">${unsuccessTip}</span> </div>` options.container.innerHTML = template }
.sliderBox{ width:350px; height:40px; border:1px solid #aaa; position:relative; background:#E7E7E7; } .slide-btn{ position:absolute; height:40px; width:40px; border-right:1px solid #aaa; background:rgba(255,255,255,.9); top:0; left:0; z-index:5; cursor: default; line-height:40px; text-align: center; color:#aaaaaa; user-select:none; } .notice { position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); z-index:2; display: inline-block; font-size:14px; text-align: center; user-select:none; } .slide-part{ width:0; height:100%; position:absolute; top:0; left:0; background:#23dbd1; z-index:1; }
因为这里的模板和样式都是我提前写好的,所以这里直接用就可以了,写的蛮简单的,有需求的同学可以根据自己的需求修改。
模板和样式写完了 ,我们这里可以先new一下,看看初始效果。
<div id="container"></div> <script>
......Slider类
const container = document.getElementById('container') let slider = new Slider({ container: container }) </script>
页面的渲染完成了,这时候该处理事件的绑定了, 这里为滑动块绑定mousedown,为window绑定mousemove和mouseup事件。
function $ (el) {
return document.getElementById(el)
}
[event] (options) { const box = $('box') const slidePart = $('slide-part') const btn = $('slide-btn') const notice = $('notice') const reset = () => { //如果没有滑到底,那么重新回到头部 this.start = false this.end =false this.startX = 0 this.startY = 0 this.movedSite = [] btn.style.left = 0 slidePart.style.width = 0 } const mouseDown = (e) => { //mousedown 的事件函数 this.start = true this.startX = e.clientX //将鼠标点下的时候的位置记录下来 this.startY = e.clientY this.movedSite = [] //鼠标移动的所有距离的坐标,要传给后台 ,让后台判断是否是活人拖动的.... } const mouseMove = (e) => { //mousemove的事件函数 if (this.start) { let movedX = e.clientX - this.startX //鼠标移动的横坐标距离 let movedY = e.clientY - this.startY //鼠标移动的纵坐标距离 this.movedSite.push(movedX + ',' + movedY) //将距离push到 上面定义的数组中, if (movedX < 0) { //滑块不能向左移动 movedX = 0 } btn.style.left = movedX + 'px' //滑块的left值为已经移动的X距离 slidePart.style.width = movedX + 'px' // 滑过区域的宽度为已经移动的x距离 let maxWidth = parseInt(window.getComputedStyle(box).width) - parseInt(window.getComputedStyle(btn).width) //滑块能滑的最大距离为外层box的距离减去 滑块的宽度。 if (movedX >= maxWidth) { //如果滑过的距离大于等于上面的最大距离,说明已经滑到头了 this.start = false this.end = true btn.style.left = maxWidth + 'px' slidePart.style.width = maxWidth + 'px' btn.innerHTML = '√' btn.style.color = '#23dbd1' options.success && options.success(notice, this.movedSite) //如果options里面有成功的回调函数 则调用,参数为显示文字的dom和坐标距离的数组, } } } const mouseUp = (e) => { //mouseup的事件函数 if (!this.end) { //如果没有滑到头,那么就从新reset,从头再来 reset() } else { //滑到头的话 就将这三个事件移除掉 btn.removeEventListener('mousedown', mouseDown) window.removeEventListener('mousemove', mouseMove) window.removeEventListener('mouseup', mouseUp) } } btn.addEventListener('mousedown', mouseDown) //绑定监听事件 window.addEventListener('mousemove', mouseMove) window.addEventListener('mouseup', mouseUp) }
我们还需要对外提供一个重置的接口:
reset () { this[render](this.options) this[event](this.options) this.end =false }
这样,一个滑动验证的类就完成了。全部代码如下:
<style> #box{ margin: 300px auto; } .sliderBox{ width:350px; height:40px; border:1px solid #aaa; position:relative; background:#E7E7E7; } .slide-btn{ position:absolute; height:40px; width:40px; border-right:1px solid #aaa; background:rgba(255,255,255,.9); top:0; left:0; z-index:5; cursor: default; line-height:40px; text-align: center; color:#aaaaaa; user-select:none; } .notice { position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); z-index:2; display: inline-block; font-size:14px; text-align: center; user-select:none; } .slide-part{ width:0; height:100%; position:absolute; top:0; left:0; background:#23dbd1; z-index:1; } </style> <body> <div id="container"> </div> <script> function $(dom) { return document.getElementById(dom) } const event = Symbol('event') const render = Symbol('render') class Slider { constructor(options) { this.options = options if (!options.container) { throw new Error ('slide必须传入container配置') } else { this[render](options) this[event](options) } } [render] (options) { const unsuccessTip = options.unsuccessTip || '请拖动滑块到最右边' const template = ` <div class="sliderBox" id="box"> <div class="slide-part" id="slide-part"></div> <div class="slide-btn" id="slide-btn">>></div> <span class="notice" id="notice">${unsuccessTip}</span> </div>` options.container.innerHTML = template } [event] (options) { const box = $('box') const slidePart = $('slide-part') const btn = $('slide-btn') const notice = $('notice') const reset = () => { this.start = false this.end =false this.startX = 0 this.startY = 0 this.movedSite = [] btn.style.left = 0 slidePart.style.width = 0 } const mouseDown = (e) => { this.start = true this.startX = e.clientX this.startY = e.clientY this.movedSite = [] } const mouseMove = (e) => { if (this.start) { let movedX = e.clientX - this.startX let movedY = e.clientY - this.startY this.movedSite.push(movedX + ',' + movedY) if (movedX < 0) { movedX = 0 } btn.style.left = movedX + 'px' slidePart.style.width = movedX + 'px' let maxWidth = parseInt(window.getComputedStyle(box).width) - parseInt(window.getComputedStyle(btn).width) if (movedX >= maxWidth) { this.start = false this.end = true btn.style.left = maxWidth + 'px' slidePart.style.width = maxWidth + 'px' btn.innerHTML = '√' btn.style.color = '#23dbd1' options.success && options.success(notice, this.movedSite) } } } const mouseUp = (e) => { if (!this.end) { reset() } else { btn.removeEventListener('mousedown', mouseDown) window.removeEventListener('mousemove', mouseMove) window.removeEventListener('mouseup', mouseUp) } } btn.addEventListener('mousedown', mouseDown) window.addEventListener('mousemove', mouseMove) window.addEventListener('mouseup', mouseUp) } reset () { this[render](this.options) this[event](this.options) this.end =false } }
const container = $('container')
let slide = new Slider({
container: container,
success: (notice, arr) => {
console.log(notice)
console.log(arr)
}
})
</script>
</body>
这样我们通过success函数就可以获取到 显示文字的dom元素和滑动距离的数组 。 将滑动距离的数组传给后台,判断是否为活人滑动的,将结果显示在显示文字的dom元素里面,就大功告成了。
需要重置滑动验证的话,可以直接调用 slide.reset()