您所在的位置: > 主页 > 上海视点 > 资讯 > 正文
原生JS封装拖动验证滑块你会吗?「实践」来源: 日期:2020-09-25 11:32:38  阅读:-


    原生JS封装拖动验证滑块你会吗?「实践」

    作者:_release

    转发链接:https://juejin.im/post/5ed37a73e51d45788c739784

    前言

    星期六闲着没事,就想着写写原生js玩玩,在网上看了几个效果后决定做这个效果,并且使用了prototype和eventEmitter封装成了库。

    最终效果


    原生JS封装拖动验证滑块你会吗?「实践」


    分析

    看到这个效果我们首先应该想到和拖动有关的api: onmousedown, onmousemove, onmouseup

    其次要支持用户传入放置这个组件的dom元素和完成的回调事件。

    最终如何使用?

    我们先来看下使用方式,再来决定我们怎么编写这个库


    原生JS封装拖动验证滑块你会吗?「实践」


    具体使用就是这样的,我们还想用户能通过import等方式使用,所以我们就要支持esMoudule的导入方式。

    编写库的整体初始框架

    (function () {
    // =================代码块1=========================================
    var root = (typeof self == 'object' && self.self == self && self) ||
    (typeof global == 'object' && global.global == global && global) ||
    this || {};
    var util = {
    extend: function (target) {
    for (var i = 1, len = arguments.length; i < len; i++) {
    for (var prop in arguments[i]) {
    if (arguments[i].hasOwnProperty(prop)) {
    target[prop] = arguments[i][prop]
    }
    }
    }
    return target
    },
    isValidListener: function (listener) {
    if (typeof listener === 'function') {
    return true
    } else if (listener && typeof listener === 'object') {
    return util.isValidListener(listener.listener)
    } else {
    return false
    }
    },
    addCSS: function (cssText) {
    var style = document.createElement('style'), //创建一个style元素
    head = document.head || document.getElementsByTagName('head')[0]; //获取head元素
    style.type = 'text/css'; //这里必须显示设置style元素的type属性为text/css,否则在ie中不起作用
    if (style.styleSheet) { //IE
    var func = function () {
    try { //防止IE中stylesheet数量超过限制而发生错误
    style.styleSheet.cssText = cssText;
    } catch (e) {

    }
    }
    //如果当前styleSheet还不能用,则放到异步中则行
    if (style.styleSheet.disabled) {
    setTimeout(func, 10);
    } else {
    func();
    }
    } else { //w3c
    //w3c浏览器中只要创建文本节点插入到style元素中就行了
    var textNode = document.createTextNode(cssText);
    style.appendChild(textNode);
    }
    head.appendChild(style); //把创建的style元素插入到head中
    },
    indexOf: function (array, item) {
    if (array.indexOf) {
    return array.indexOf(item);
    } else {
    var result = -1;
    for (var i = 0, len = array.length; i < len; i++) {
    if (array[i] === item) {
    result = i;
    break;
    }
    }
    return result;
    }
    }
    }

    function EventEmitter() {
    this._events = {}
    }

    EventEmitter.prototype.on = function (eventName, listener) {
    if (!eventName || !listener) return;
    if (!util.isValidListener(listener)) {
    throw new TypeError('listener must be a function');
    }
    var events = this._events;
    var listeners = events[eventName] = events[eventName] || [];
    var listenerIsWrapped = typeof listener === 'object';
    // 不重复添加事件
    if (util.indexOf(listeners, listener) === -1) {
    listeners.push(listenerIsWrapped ? listener : {
    listener: listener,
    once: false
    });
    }
    return this;
    };
    EventEmitter.prototype.once = function (eventName, listener) {
    return this.on(eventName, {
    listener: listener,
    once: true
    })
    };
    EventEmitter.prototype.off = function (eventName, listener) {
    var listeners = this._events[eventName];
    if (!listeners) return;
    var index;
    for (var i = 0, len = listeners.length; i < len; i++) {
    if (listeners[i] && listeners[i].listener === listener) {
    index = i;
    break;
    }
    }
    if (typeof index !== 'undefined') {
    listeners.splice(index, 1, null)
    }
    return this;
    };
    EventEmitter.prototype.emit = function (eventName, args) {
    var listeners = this._events[eventName];
    if (!listeners) return;
    for (var i = 0; i < listeners.length; i++) {
    var listener = listeners[i];
    if (listener) {
    listener.listener.apply(this, args || []);
    if (listener.once) {
    this.off(eventName, listener.listener)
    }
    }
    }
    return this;
    };

    // =================代码块2=========================================
    function SliderTools(options) {
    this.options = util.extend({}, this.constructor.defaultOptions, options)
    this.init();
    this.bindEvents();
    this.diffX = 0;
    this.flag = false;//是否拖动到最右侧
    }

    SliderTools.defaultOptions = {
    el: document.body //默认放到body里
    };

    var proto = SliderTools.prototype = new EventEmitter();//SliderTools继承emitter

    proto.constructor = SliderTools;//修正构造器

    proto.init = function () {
    this.createSlider();//创建插件所需要的dom元素
    this.getElements();//获取创建好的元素
    }

    // =================代码块3=========================================
    if (typeof exports != 'undefined' && !exports.nodeType) {
    if (typeof module != 'undefined' && !module.nodeType && module.exports) {
    exports = module.exports = SliderTools;
    }
    exports.SliderTools = SliderTools;
    } else {
    root.SliderTools = SliderTools;
    }
    }());
    复制代码

    代码块1是在判断是在浏览器环境还是nodeJS环境,方便代码三后期使用, 代码块2声明了一个对象SliderTools,将用户传进来的option和默认的defaultOption进行合并

    编写核心函数1(创建dom和css)

    proto.createSlider = function () {
    this.options.el.innerHTML = '
    拖动滑块验证
    ';//像指定元素中放置插件的dom元素
    util.addCSS('ul,li {list-style: none;} a {text-decoration: none;} .wrap {width: 300px;height: 350px;text-align: center;margin: 150px auto;}.inner {padding: 15px;} .clearfix {overflow: hidden;_zoom: 1;} .none {display: none;} #slider {position:relative;background-color: #e8e8e8;width: 300px;height: 34px;line-height: 34px;text-align: center;} #slider .handler {position: absolute;top: 0px;left: 0px;width: 40px;height: 32px;border: 1px solid #ccc;cursor: move;} .handler_bg {background: #fff url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo0ZDhlNWY5My05NmI0LTRlNWQtOGFjYi03ZTY4OGYyMTU2ZTYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NTEyNTVEMURGMkVFMTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTEyNTVEMUNGMkVFMTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2MTc5NzNmZS02OTQxLTQyOTYtYTIwNi02NDI2YTNkOWU5YmUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NGQ4ZTVmOTMtOTZiNC00ZTVkLThhY2ItN2U2ODhmMjE1NmU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+YiRG4AAAALFJREFUeNpi/P//PwMlgImBQkA9A+bOnfsIiBOxKcInh+yCaCDuByoswaIOpxwjciACFegBqZ1AvBSIS5OTk/8TkmNEjwWgQiUgtQuIjwAxUF3yX3xyGIEIFLwHpKyAWB+I1xGSwxULIGf9A7mQkBwTlhBXAFLHgPgqEAcTkmNCU6AL9d8WII4HOvk3ITkWJAXWUMlOoGQHmsE45ViQ2KuBuASoYC4Wf+OUYxz6mQkgwAAN9mIrUReCXgAAAABJRU5ErkJggg==") no-repeat center;} .handler_ok_bg {background: #fff url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo0ZDhlNWY5My05NmI0LTRlNWQtOGFjYi03ZTY4OGYyMTU2ZTYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDlBRDI3NjVGMkQ2MTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDlBRDI3NjRGMkQ2MTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDphNWEzMWNhMC1hYmViLTQxNWEtYTEwZS04Y2U5NzRlN2Q4YTEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NGQ4ZTVmOTMtOTZiNC00ZTVkLThhY2ItN2U2ODhmMjE1NmU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+k+sHwwAAASZJREFUeNpi/P//PwMyKD8uZw+kUoDYEYgloMIvgHg/EM/ptHx0EFk9I8wAoEZ+IDUPiIMY8IN1QJwENOgj3ACo5gNAbMBAHLgAxA4gQ5igAnNJ0MwAVTsX7IKyY7L2UNuJAf+AmAmJ78AEDTBiwGYg5gbifCSxFCZoaBMCy4A4GOjnH0D6DpK4IxNSVIHAfSDOAeLraJrjgJp/AwPbHMhejiQnwYRmUzNQ4VQgDQqXK0ia/0I17wJiPmQNTNBEAgMlQIWiQA2vgWw7QppBekGxsAjIiEUSBNnsBDWEAY9mEFgMMgBk00E0iZtA7AHEctDQ58MRuA6wlLgGFMoMpIG1QFeGwAIxGZo8GUhIysmwQGSAZgwHaEZhICIzOaBkJkqyM0CAAQDGx279Jf50AAAAAABJRU5ErkJggg==") no-repeat center;}#slider .drag_bg {background-color: #7ac23c; height: 34px;width: 0px;} #slider .drag_text {position: absolute; top: 0px;width: 300px;-moz-user-select: none;-webkit-user-select: none;user-select: none;-o-user-select: none;-ms-user-select: none; }.unselect {-moz-user-select: none;-webkit-user-select: none; -ms-user-select: none;}.slide_ok {color: #fff;}')//像页面里add新的样式
    }
    proto.getElements = function () {
    this.slider = document.querySelector('#slider');
    this.drag_bg = document.querySelector('.drag_bg');
    this.handler = document.querySelector('.handler');
    }
    复制代码

    编写核心函数2(绑定事件)

    proto.bindEvents = function () {
    var self = this;
    self.handler.onmousedown = function (e) {
    self.diffX = e.clientX - self.handler.offsetLeft;
    util.setClassName(self.slider, 'unselect'); //禁止选择样式
    document.onmousemove = function (e) {
    let deltaX = e.clientX - self.diffX;
    if (deltaX >= self.slider.offsetWidth - self.handler.offsetWidth) { //拖动到了最右侧
    deltaX = self.slider.offsetWidth - self.handler.offsetWidth;
    self.flag = true;
    } else if (deltaX <= 0) {
    deltaX = 0;
    self.flag = false;
    } else {
    self.flag = false;
    }
    util.setInlineStyle([self.handler], 'left', deltaX + 'px');
    util.setInlineStyle([self.drag_bg], 'width', deltaX + 'px');
    }
    document.onmouseup = function (e) {
    util.setClassName(self.slider, '')
    if (self.flag) {
    util.setClassName(self.slider, 'slide_ok') //拖动完成后的样式
    util.addClass(self.handler, 'handler_ok_bg')////拖动完成后的样式
    self.handler.onmousedown = null //防止拖动完成后再次拖动
    self.emit('complete')//emit通知使用者的回调事件
    } else {
    util.setInlineStyle([self.handler], 'left', 0 + 'px');
    util.setInlineStyle([self.drag_bg], 'width', 0 + 'px');
    }
    document.onmousemove = null;
    document.onmouseup = null;
    }
    }
    }
    复制代码

    添加工具方法(核心函数2中用到的)

    var util = {
    // ...初始框架里的那部分
    setClassName(selector, className) {
    selector.className = className;
    },
    addClass(selector, className) {
    selector.classList.add(className);
    },
    setInlineStyle(selector, attr, content) {
    let length = selector.length;
    for (let i = 0; i < length; i++) {
    selector[i].style[attr] = content;
    }
    },
    }
    复制代码

    最终完整可运行代码

    (function () {
    var root = (typeof self == 'object' && self.self == self && self) ||
    (typeof global == 'object' && global.global == global && global) ||
    this || {};
    var util = {
    extend: function (target) {
    for (var i = 1, len = arguments.length; i < len; i++) {
    for (var prop in arguments[i]) {
    if (arguments[i].hasOwnProperty(prop)) {
    target[prop] = arguments[i][prop]
    }
    }
    }
    return target
    },
    setClassName(selector, className) {
    selector.className = className;
    },
    addClass(selector, className) {
    selector.classList.add(className);
    },
    setInlineStyle(selector, attr, content) {
    let length = selector.length;
    for (let i = 0; i < length; i++) {
    selector[i].style[attr] = content;
    }
    },
    isValidListener: function (listener) {
    if (typeof listener === 'function') {
    return true
    } else if (listener && typeof listener === 'object') {
    return util.isValidListener(listener.listener)
    } else {
    return false
    }
    },
    addCSS: function (cssText) {
    var style = document.createElement('style'), //创建一个style元素
    head = document.head || document.getElementsByTagName('head')[0]; //获取head元素
    style.type = 'text/css'; //这里必须显示设置style元素的type属性为text/css,否则在ie中不起作用
    if (style.styleSheet) { //IE
    var func = function () {
    try { //防止IE中stylesheet数量超过限制而发生错误
    style.styleSheet.cssText = cssText;
    } catch (e) {

    }
    }
    //如果当前styleSheet还不能用,则放到异步中则行
    if (style.styleSheet.disabled) {
    setTimeout(func, 10);
    } else {
    func();
    }
    } else { //w3c
    //w3c浏览器中只要创建文本节点插入到style元素中就行了
    var textNode = document.createTextNode(cssText);
    style.appendChild(textNode);
    }
    head.appendChild(style); //把创建的style元素插入到head中
    },
    indexOf: function (array, item) {
    if (array.indexOf) {
    return array.indexOf(item);
    } else {
    var result = -1;
    for (var i = 0, len = array.length; i < len; i++) {
    if (array[i] === item) {
    result = i;
    break;
    }
    }
    return result;
    }
    }
    }

    function EventEmitter() {
    this._events = {}
    }

    EventEmitter.prototype.on = function (eventName, listener) {
    if (!eventName || !listener) return;

    if (!util.isValidListener(listener)) {
    throw new TypeError('listener must be a function');
    }

    var events = this._events;
    var listeners = events[eventName] = events[eventName] || [];
    var listenerIsWrapped = typeof listener === 'object';

    // 不重复添加事件
    if (util.indexOf(listeners, listener) === -1) {
    listeners.push(listenerIsWrapped ? listener : {
    listener: listener,
    once: false
    });
    }

    return this;
    };
    EventEmitter.prototype.once = function (eventName, listener) {
    return this.on(eventName, {
    listener: listener,
    once: true
    })
    };
    EventEmitter.prototype.off = function (eventName, listener) {
    var listeners = this._events[eventName];
    if (!listeners) return;

    var index;
    for (var i = 0, len = listeners.length; i < len; i++) {
    if (listeners[i] && listeners[i].listener === listener) {
    index = i;
    break;
    }
    }

    if (typeof index !== 'undefined') {
    listeners.splice(index, 1, null)
    }

    return this;
    };
    EventEmitter.prototype.emit = function (eventName, args) {
    var listeners = this._events[eventName];
    if (!listeners) return;

    for (var i = 0; i < listeners.length; i++) {
    var listener = listeners[i];
    if (listener) {
    listener.listener.apply(this, args || []);
    if (listener.once) {
    this.off(eventName, listener.listener)
    }
    }
    }
    return this;
    };

    function SliderTools(options) {
    this.options = util.extend({}, this.constructor.defaultOptions, options)
    this.init();
    this.bindEvents();
    this.diffX = 0;
    this.flag = false;
    }

    SliderTools.VERSION = '1.0.0';

    SliderTools.defaultOptions = {
    el: document.body
    };

    var proto = SliderTools.prototype = new EventEmitter();

    proto.constructor = SliderTools;

    proto.init = function () {
    this.createSlider();
    this.getElements();
    }

    proto.createSlider = function () {
    this.options.el.innerHTML = '
    拖动滑块验证
    ';
    util.addCSS('ul, li { list-style: none; } a { text-decoration: none; } .wrap { width: 300px; height: 350px; text-align: center; margin: 150px auto; } .inner { padding: 15px; } .clearfix { overflow: hidden; _zoom: 1; } .none { display: none; } #slider { position: relative; background-color: #e8e8e8; width: 300px; height: 34px; line-height: 34px; text-align: center; } #slider .handler { position: absolute; top: 0px; left: 0px; width: 40px; height: 32px; border: 1px solid #ccc; cursor: move;} .handler_bg { background: #fff url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo0ZDhlNWY5My05NmI0LTRlNWQtOGFjYi03ZTY4OGYyMTU2ZTYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NTEyNTVEMURGMkVFMTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTEyNTVEMUNGMkVFMTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2MTc5NzNmZS02OTQxLTQyOTYtYTIwNi02NDI2YTNkOWU5YmUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NGQ4ZTVmOTMtOTZiNC00ZTVkLThhY2ItN2U2ODhmMjE1NmU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+YiRG4AAAALFJREFUeNpi/P//PwMlgImBQkA9A+bOnfsIiBOxKcInh+yCaCDuByoswaIOpxwjciACFegBqZ1AvBSIS5OTk/8TkmNEjwWgQiUgtQuIjwAxUF3yX3xyGIEIFLwHpKyAWB+I1xGSwxULIGf9A7mQkBwTlhBXAFLHgPgqEAcTkmNCU6AL9d8WII4HOvk3ITkWJAXWUMlOoGQHmsE45ViQ2KuBuASoYC4Wf+OUYxz6mQkgwAAN9mIrUReCXgAAAABJRU5ErkJggg==") no-repeat center; } .handler_ok_bg { background: #fff url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo0ZDhlNWY5My05NmI0LTRlNWQtOGFjYi03ZTY4OGYyMTU2ZTYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDlBRDI3NjVGMkQ2MTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDlBRDI3NjRGMkQ2MTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDphNWEzMWNhMC1hYmViLTQxNWEtYTEwZS04Y2U5NzRlN2Q4YTEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NGQ4ZTVmOTMtOTZiNC00ZTVkLThhY2ItN2U2ODhmMjE1NmU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+k+sHwwAAASZJREFUeNpi/P//PwMyKD8uZw+kUoDYEYgloMIvgHg/EM/ptHx0EFk9I8wAoEZ+IDUPiIMY8IN1QJwENOgj3ACo5gNAbMBAHLgAxA4gQ5igAnNJ0MwAVTsX7IKyY7L2UNuJAf+AmAmJ78AEDTBiwGYg5gbifCSxFCZoaBMCy4A4GOjnH0D6DpK4IxNSVIHAfSDOAeLraJrjgJp/AwPbHMhejiQnwYRmUzNQ4VQgDQqXK0ia/0I17wJiPmQNTNBEAgMlQIWiQA2vgWw7QppBekGxsAjIiEUSBNnsBDWEAY9mEFgMMgBk00E0iZtA7AHEctDQ58MRuA6wlLgGFMoMpIG1QFeGwAIxGZo8GUhIysmwQGSAZgwHaEZhICIzOaBkJkqyM0CAAQDGx279Jf50AAAAAABJRU5ErkJggg==") no-repeat center; } #slider .drag_bg { background-color: #7ac23c; height: 34px; width: 0px; } #slider .drag_text { position: absolute; top: 0px; width: 300px; -moz-user-select: none; -webkit-user-select: none; user-select: none; -o-user-select: none; -ms-user-select: none; } .unselect { -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none; } .slide_ok { color: #fff; }')
    }
    proto.getElements = function () {
    this.slider = document.querySelector('#slider');
    this.drag_bg = document.querySelector('.drag_bg');
    this.handler = document.querySelector('.handler');
    }
    proto.bindEvents = function () {
    var self = this;
    self.handler.onmousedown = function (e) {
    self.diffX = e.clientX - self.handler.offsetLeft;
    util.setClassName(self.slider, 'unselect');
    document.onmousemove = function (e) {
    let deltaX = e.clientX - self.diffX;
    if (deltaX >= self.slider.offsetWidth - self.handler.offsetWidth) {
    deltaX = self.slider.offsetWidth - self.handler.offsetWidth;
    self.flag = true;
    } else if (deltaX <= 0) {
    deltaX = 0;
    self.flag = false;
    } else {
    self.flag = false;
    }
    util.setInlineStyle([self.handler], 'left', deltaX + 'px');
    util.setInlineStyle([self.drag_bg], 'width', deltaX + 'px');
    }
    document.onmouseup = function (e) {
    util.setClassName(self.slider, '')
    if (self.flag) {
    util.setClassName(self.slider, 'slide_ok')
    util.addClass(self.handler, 'handler_ok_bg')
    self.handler.onmousedown = null
    self.emit('complete')
    } else {
    util.setInlineStyle([self.handler], 'left', 0 + 'px');
    util.setInlineStyle([self.drag_bg], 'width', 0 + 'px');
    }
    document.onmousemove = null;
    document.onmouseup = null;
    }
    }
    }
    if (typeof exports != 'undefined' && !exports.nodeType) {
    if (typeof module != 'undefined' && !module.nodeType && module.exports) {
    exports = module.exports = SliderTools;
    }
    exports.SliderTools = SliderTools;
    } else {
    root.SliderTools = SliderTools;
    }
    }());

    let slider = new SliderTools();
    slider.on('complete',() => {
    alert('验证完成');
    })

    推荐JavaScript经典实例学习资料文章

    如何实现高性能的在线 PDF 预览

    细说使用字体库加密数据-仿58同城

    Node.js要完了吗?

    Pug 3.0.0正式发布,不再支持 Node.js 6/8

    纯JS手写轮播图(代码逻辑清晰,通俗易懂)

    JavaScript 20 年 中文版之创立标准

    值得收藏的前端常用60余种工具方法「JS篇」

    箭头函数和常规函数之间的 5 个区别

    通过发布/订阅的设计模式搞懂 Node.js 核心模块 Events

    「前端篇」不再为正则烦恼

    「速围」Node.js V14.3.0 发布支持顶级 Await 和 REPL 增强功能

    深入细品浏览器原理「流程图」

    JavaScript 已进入第三个时代,未来将何去何从?

    前端上传前预览文件 image、text、json、video、audio「实践」

    深入细品 EventLoop 和浏览器渲染、帧动画、空闲回调的关系

    推荐13个有用的JavaScript数组技巧「值得收藏」

    前端必备基础知识:window.location 详解

    不要再依赖CommonJS了

    犀牛书作者:最该忘记的JavaScript特性

    36个工作中常用的JavaScript函数片段「值得收藏」

    Node + H5 实现大文件分片上传、断点续传

    一文了解文件上传全过程(1.8w字深度解析)「前端进阶必备」

    【实践总结】关于小程序挣脱枷锁实现批量上传

    手把手教你前端的各种文件上传攻略和大文件断点续传

    字节跳动面试官:请你实现一个大文件上传和断点续传

    谈谈前端关于文件上传下载那些事【实践】

    手把手教你如何编写一个前端图片压缩、方向纠正、预览、上传插件

    最全的 JavaScript 模块化方案和工具

    「前端进阶」JS中的内存管理

    JavaScript正则深入以及10个非常有意思的正则实战

    前端面试者经常忽视的一道JavaScript 面试题

    一行JS代码实现一个简单的模板字符串替换「实践」

    JS代码是如何被压缩的「前端高级进阶」

    前端开发规范:命名规范、html规范、css规范、js规范

    【规范篇】前端团队代码规范最佳实践

    100个原生JavaScript代码片段知识点详细汇总【实践】

    关于前端174道 JavaScript知识点汇总(一)

    关于前端174道 JavaScript知识点汇总(二)

    关于前端174道 JavaScript知识点汇总(三)

    几个非常有意思的javascript知识点总结【实践】

    都2020年了,你还不会JavaScript 装饰器?

    JavaScript实现图片合成下载

    70个JavaScript知识点详细总结(上)【实践】

    70个JavaScript知识点详细总结(下)【实践】

    开源了一个 JavaScript 版敏感词过滤库

    送你 43 道 JavaScript 面试题

    3个很棒的小众JavaScript库,你值得拥有

    手把手教你深入巩固JavaScript知识体系【思维导图】

    推荐7个很棒的JavaScript产品步骤引导库

    Echa哥教你彻底弄懂 JavaScript 执行机制

    一个合格的中级前端工程师需要掌握的 28 个 JavaScript 技巧

    深入解析高频项目中运用到的知识点汇总【JS篇】

    JavaScript 工具函数大全【新】

    从JavaScript中看设计模式(总结)

    身份证号码的正则表达式及验证详解(JavaScript,Regex)

    浏览器中实现JavaScript计时器的4种创新方式

    Three.js 动效方案

    手把手教你常用的59个JS类方法

    127个常用的JS代码片段,每段代码花30秒就能看懂-【上】

    深入浅出讲解 js 深拷贝 vs 浅拷贝

    手把手教你JS开发H5游戏【消灭星星】

    深入浅出讲解JS中this/apply/call/bind巧妙用法【实践】

    手把手教你全方位解读JS中this真正含义【实践】

    书到用时方恨少,一大波JS开发工具函数来了

    干货满满!如何优雅简洁地实现时钟翻牌器(支持JS/Vue/React)

    手把手教你JS 异步编程六种方案【实践】

    让你减少加班的15条高效JS技巧知识点汇总【实践】

    手把手教你JS开发H5游戏【黄金矿工】

    手把手教你JS实现监控浏览器上下左右滚动

    JS 经典实例知识点整理汇总【实践】

    2.6万字JS干货分享,带你领略前端魅力【基础篇】

    2.6万字JS干货分享,带你领略前端魅力【实践篇】

    简单几步让你的 JS 写得更漂亮

    恭喜你获得治疗JS this的详细药方

    谈谈前端关于文件上传下载那些事【实践】

    面试中教你绕过关于 JavaScript 作用域的 5 个坑

    Jquery插件(常用的插件库)

    【JS】如何防止重复发送ajax请求

    JavaScript+Canvas实现自定义画板

    Continuation 在 JS 中的应用「前端篇」


    作者:_release
    转发链接:https://juejin.im/post/5ed37a73e51d45788c739784

    (正文已结束)

    免责声明及提醒:此文内容为本网所转载企业宣传资讯,该相关信息仅为宣传及传递更多信息之目的,不代表本网站观点,文章真实性请浏览者慎重核实!任何投资加盟均有风险,提醒广大民众投资需谨慎!