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()

    

    

posted @ 2018-12-27 09:58  ken丶123  阅读(856)  评论(0编辑  收藏  举报