原生JS封装拖动验证滑块

  • 最终效果
  • 分析
  • 最终如何使用?
  • 编写库的整体初始框架
    • 编写核心函数1(创建dom和css)
    • 编写核心函数2(绑定事件)
    • 添加工具方法(核心函数2中用到的)
  • 最终完整可运行代码
  • 使用

最终效果

分析

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

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

最终如何使用?

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

编写库的整体初始框架

(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) { //IEvar 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继承emitterproto.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\color{#FF3030}{SliderTools}SliderTools,将用户传进来的option\color{#FF3030}{option}option和默认的defaultOption\color{#FF3030}{defaultOption}defaultOption进行合并

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

proto.createSlider = function () {this.options.el.innerHTML = '<div id="slider"><div class="drag_bg"></div><div class="drag_text" onselectstart="return false;" unselectable="on">拖动滑块验证</div><div class="handler handler_bg"></div></div>';//像指定元素中放置插件的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) { //IEvar 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 = '<div id="slider"><div class="drag_bg"></div><div class="drag_text" onselectstart="return false;" unselectable="on">拖动滑块验证</div><div class="handler handler_bg"></div></div>';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 = nullself.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('验证完成');
})

使用

<script src="./SliderTools.js"></script>

或者

import SliderTools from './SliderTools.js'

JavaScript封装拖动滑块验证相关推荐

  1. JavaScript实现拖动滑块验证(方法已封装)

    前提 之前写了一篇博文,题目是<JavaScript实现拖动滑块验证>,里面都是用最简单的方式实现的.后来,群里大神推荐了一款unlock.js插件,称作幻灯片解锁插件.在这里附上它的gi ...

  2. JavaScript实现拖动滑块验证

    Write By Monkeyfly 以下内容均为原创,如需转载请注明出处. 前提 之前在优化别人写的登录界面时,遇到了滑动解锁成功后发送短信验证码的场景,因为涉及到改动,所以必须要明白它是怎么实现的 ...

  3. jQuery手机触屏拖动滑块验证跳转插件

    HTML: <!DOCTYPE html> <html lang="en"> <head> <title>jQuery手机触屏拖动滑 ...

  4. 拖动滑块验证——原生JS

    ** 拖动滑块验证--原生JS ** 大体思路: 1,拖动滑块验证我们首先要分析需要什么事件,怎么触发拖动滑块. 2,首先需要点击事件,当你点击鼠标的时候获取到一个X轴的距离. 3,还需要一个鼠标移动 ...

  5. jQuery拖动滑块验证样式

    样式: 目录结构: HTML代码: <!DOCTYPE html> <html><head><title>jQuery仿淘宝网拖动滑块验证码代码< ...

  6. vue拖动滑块验证组件

    组件Slider.vue <template><div class="drag" ref="dragDiv"><div class ...

  7. 拖动滑块验证--vue实现

    代码引用的css与js都是线上的 将代码全部复制到一个html中可以直接打开,极其简单. 来分析一下代码 底色div上放了一个变色div再放一个提示字的div最后加一个滑块div 给滑块div绑定鼠标 ...

  8. css3 滑动验证,Vue 实现拖动滑块验证功能(只有css+js没有后台验证步骤)

    vue验证滑块功能,在生活中很多地方都可以见到,那么使用起来非常方便,基于vue如何实现滑块验证呢?下面通过代码给大家讲解. 效果图如下所示: 拖动前 拖动后 代码引用的css与js都是线上的 将代码 ...

  9. 原生js实现拖动滑块验证

    拖动滑块验证是现在的网站随处可见的,各式各样的拖动法都有. 下面实现的是某宝的拖动滑块验证: <!DOCTYPE html> <html lang="en"> ...

  10. 小程序 拖动滑块验证(自定义组件 插件分享)

    效果图: 文章目录: #1 创建组件 #2 组件编码 MoveVerify.wxss MoveVerify.wxml MoveVerify.js #3 页面引用 在页面的 json 文件中引用组件 在 ...

最新文章

  1. 发觉好像视力户籍变差么。。
  2. JavaScript实现permutate Without Repetitions无重复排列算法(附完整源码)
  3. 授人以鱼不如授人以渔——CPU漏洞的Symantec解决之道
  4. python登录网站 爬虫_Python爬虫如何使用Cookies登录网站
  5. [jQuery] 针对jQuery性能的优化方法有哪些?
  6. 燕山大学数字通信计算机仿真代码,燕山大学数字通信计算机仿真课程设计模板.doc...
  7. python交互式绘图比较_python – 基于Tkinter和matplotlib的交互式绘图
  8. 【我的物联网成长记7】物联网主流通信协议解读【华为云分享】
  9. c语言函数可变长参数,一种使用变长参数为C程序构造灵活回调函数的方法
  10. linux ssh 双机互信
  11. css3:box-shadow
  12. Citrix XenApp/XenDesktop 7.15 LTSR发布
  13. docker镜像下载的网站
  14. zabbix监控软件的安装,详细教程
  15. 高德地图经纬度比较并返回范围内要求个数可用
  16. 期权定价公式的推导(欧式)
  17. 素数五个为一行的_帕斯卡三角形与素数
  18. 部分女生爱搭配蕾丝的服饰
  19. app中跳转到手机浏览器,部分手机白屏解决(Vue)
  20. Git新手入门视频教程

热门文章

  1. vue 实现计算器功能
  2. WSL2 Docker Distro迁移
  3. android jcenter google 镜像
  4. 微信公众号软件安装管家所有软件插件打包
  5. 南京最最最牛逼的 IT 公司全在这了
  6. word大纲视图快速转成PPT
  7. 像素、分辨率、尺寸概念与关系
  8. 微信公众号网页授权并获取用户信息简要流程
  9. 1-MySQL事务特性
  10. 8g内存和16g内存区别 mac_内存不重要?8G内存和16G内存的M1 MacBook Pro性能对比