好玩的.滑块验证

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        #wrapper {
            border: 1px solid red;
            width: 200px;
            height: 30px;
        }
    </style>
</head>

<body>
    <div id="wrapper">
        <div id="test"></div>
    </div>
    <script>
        // 暂时只有向右运动
        const PositionMove = function () {
            let id = 0;
            class PositionMove {
                constructor({ el, direction = 'right' }) {
                    this.id = ++id;
                    this.el = el;
                    this.elWidth = el.offsetWidth;
                    const parent = el.parentNode;
                    this.parent = parent;
                    this.parentOffsetLeftWithClient = parent.getBoundingClientRect().left;
                    //
                    this.isToggleTouchend = false;
                    this.done = false;
                    this.start = 0;
                    this.end = parent.offsetWidth - this.elWidth;
                    this.init();
                }
                init() {
                    this.isOnMove = false;
                    // 貌似占内存了
                    Object.assign(this, {
                        touchstart: this.touchstart.bind(this),
                        touchend: this.touchend.bind(this),
                        touchmove: this.touchmove.bind(this),
                    });
                    this.bindEvents();
                }

                destory() {
                    this.unbindEvents();
                    Object.keys(this).forEach(k => {
                        delete this[k];
                    });
                    console.log(this);
                }
                bindEvents() {
                    this.parent.addEventListener('mousedown', this.touchstart);
                    this.parent.addEventListener('mouseup', this.touchend);
                    this.parent.addEventListener('mouseleave', this.touchend);
                    this.parent.addEventListener('mousemove', this.touchmove, { passive: true });
                }
                unbindEvents() {
                    this.parent.removeEventListener('mousedown', this.touchstart);
                    this.parent.removeEventListener('mouseup', this.touchend);
                    this.parent.removeEventListener('mouseleave', this.touchend);
                    this.parent.removeEventListener('mousemove', this.touchmove, { passive: true });
                }
                touchstart() {
                    this.isOnMove = true;
                    this.isToggleTouchend = false;
                }
                touchend(evt) {
                    // fix 鼠标滑过
                    if (evt.type === 'mouseleave' && !this.isOnMove) return;
                    if (this.isToggleTouchend) return;
                    this.isToggleTouchend = true;
                    this.isOnMove = false;
                    if (!this.done) {
                        this.el.style.left = '0';
                    } else {
                        this.el.style.left = (this.start = this.end) + 'px';
                    }
                    this.notify();
                }
                touchmove(evt) {
                    if (!this.isOnMove) return;
                    this.start = evt.clientX - this.parentOffsetLeftWithClient;
                    this.el.style.left = this.start + 'px';
                    if (this.start >= this.end) {
                        this.done = true;
                        this.touchend(evt);
                        this.destory();
                        return;
                    }
                    // 因为会有误差,最后一次通知交由touchend处理
                    this.notify();
                }
                notify() {
                    this.onchange && this.onchange({
                        start: this.start,
                        end: this.end,
                    });
                    if (!this.isOnMove) {
                        if (this.done) {
                            this.onsuccess && this.onsuccess();
                        } else {
                            this.oncancel && this.oncancel();
                        }
                    }
                }
                // interface
                // @{function} onchange
            };
            return PositionMove;
        }();

        class DragValidate {
            getEl(el) {
                el = document.querySelector(el);
                // fix el
                el.style.position = 'relative';
                el.style.height = '100%';
                el.style.userSelect = 'none';
                return el;
            }
            constructor({ el: selector, ...options }) {
                /**
                el 需要处理好样式,最后放在wrapper元素,
                因为clientWidth、scrollWidth判断不精确
                */
                const el = this.el = this.getEl(selector);
                if (!this.el) throw ('挂载失败');
                // 触发回流
                this.width = el.offsetWidth;
                this.height = el.offsetHeight;
                if (this.width === 0 || !this.height === 0) return console.log('未挂载');
                this.init();
            }
            init() {
                this.hand = this.createHand();
                this.hand.onchange = function ({ start, end }) {
                    console.log(start / end, '%');
                }
                this.hand.onsuccess = function () {
                    console.log('成功');
                }
                this.hand.oncancel = function () {
                    console.log('取消');
                }
            }
            createHand() {
                // 不修改原dom,防止用户填充自定义的东西
                const block = document.createElement('div');
                block.style.cssText = `
                position:absolute;
                left:0;
                top:0;
                bottom:0;
                width:${this.height}px;
                background-color:blue;`;
                this.el.appendChild(block);
                const action = new PositionMove({
                    el: block,
                });
                return action;
            }
        }
        const test = new DragValidate({
            el: '#test',
        });
    </script>
</body>

</html>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值