原生JS封装拖动验证滑块的实现代码示例


Posted in Javascript onJune 01, 2020

前言

星期六闲着没事,就想着写写原生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 = '<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) { //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 = '<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 = 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('验证完成');
})

结语

参考资料

到此这篇关于原生JS封装拖动验证滑块的实现代码示例的文章就介绍到这了,更多相关JS 拖动验证滑块内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
js CSS操作方法集合
Oct 31 Javascript
JS判断浏览器是否支持某一个CSS3属性的方法
Oct 17 Javascript
Javascript动态创建表格及删除行列的方法
May 15 Javascript
JavaScript检测字符串中是否含有html标签实现方法
Jul 01 Javascript
关于input全选反选恶心的异常情况
Jul 24 Javascript
利用vue.js实现被选中状态的改变方法
Feb 08 Javascript
如何用RxJS实现Redux Form
Dec 29 Javascript
一些手写JavaScript常用的函数汇总
Apr 16 Javascript
微信小程序代码上传、审核发布小程序
May 18 Javascript
Vue + Element UI图片上传控件使用详解
Aug 20 Javascript
jQuery 动画与停止动画效果实例详解
May 19 jQuery
使用Vue实现一个树组件的示例
Nov 06 Javascript
jQuery cookie的公共方法封装和使用示例
Jun 01 #jQuery
webpack安装配置与常见使用过程详解(结合vue)
Jun 01 #Javascript
使用Vue+Django+Ant Design做一个留言评论模块的示例代码
Jun 01 #Javascript
el-table树形表格表单验证(列表生成序号)
May 31 #Javascript
vue如何在用户要关闭当前网页时弹出提示的实现
May 31 #Javascript
使用原生JS实现滚轮翻页效果的示例代码
May 31 #Javascript
24个ES6方法解决JS实际开发问题(小结)
May 31 #Javascript
You might like
PHP 5.3新特性命名空间规则解析及高级功能
2010/03/11 PHP
使用php实现下载生成某链接快捷方式的解决方法
2013/05/07 PHP
解析thinkphp基本配置 convention.php
2013/06/18 PHP
Laravel 模型关联基础教程详解
2019/09/17 PHP
javascript实现的基于金山词霸网络翻译的代码
2010/01/15 Javascript
用js实现计算加载页面所用的时间
2010/04/02 Javascript
有关js的变量作用域和this指针的讨论
2010/12/16 Javascript
纯JS实现的批量图片预览加载功能
2011/08/14 Javascript
jQuery操作Select的Option上下移动及移除添加等等
2013/11/18 Javascript
javascript:void(0)的问题使用探讨
2014/04/10 Javascript
使用JavaScript刷新网页的方法
2015/06/04 Javascript
详解js中Json的语法与格式
2016/11/22 Javascript
微信小程序 引入es6 promise
2017/04/12 Javascript
vue实现商城购物车功能
2017/11/27 Javascript
javascript异常处理实现原理详解
2020/02/17 Javascript
vue自动添加浏览器兼容前后缀操作
2020/08/13 Javascript
在Python中操作字典之fromkeys()方法的使用
2015/05/21 Python
Python实现读取SQLServer数据并插入到MongoDB数据库的方法示例
2018/06/09 Python
对pytorch中的梯度更新方法详解
2019/08/20 Python
python中sort和sorted排序的实例方法
2019/08/26 Python
Django+Uwsgi+Nginx如何实现生产环境部署
2020/07/31 Python
python中的yield from语法快速学习
2020/11/06 Python
乐天旅游香港网站:日本饭店预订
2017/11/29 全球购物
在DELPHI中调用存储过程和使用内嵌SQL哪种方式更好
2016/11/22 面试题
网络工程与软件技术毕业生自荐信
2013/09/24 职场文书
初中生自我评价
2014/02/01 职场文书
九年级语文教学反思
2014/02/04 职场文书
致标枪运动员加油稿
2014/02/15 职场文书
委托公证书
2014/04/08 职场文书
医院保洁服务方案
2014/06/11 职场文书
公司领导班子民主生活会对照检查材料
2014/10/02 职场文书
护士年终个人总结
2015/02/13 职场文书
面试通知邮件
2015/04/20 职场文书
公司的力量观后感
2015/06/05 职场文书
CSS3 制作精美的定价表
2021/04/06 HTML / CSS
HTML5来实现本地文件读取和写入的实现方法
2021/05/25 HTML / CSS