原生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不是基础的基础
Dec 24 Javascript
js全屏显示显示代码的三种方法
Nov 11 Javascript
javascript删除option选项的多种方法总结
Nov 22 Javascript
js/jquery解析json和数组格式的方法详解
Jan 09 Javascript
javascript中sort() 方法使用详解
Aug 30 Javascript
再谈Javascript中的基本类型和引用类型(推荐)
Jul 01 Javascript
javascript十六进制数字和ASCII字符之间的转换方法
Dec 27 Javascript
jQuery实现联动下拉列表查询框
Jan 04 Javascript
Angular实现一个简单的多选复选框的弹出框指令实例
Apr 25 Javascript
vue cli使用融云实现聊天功能的实例代码
Apr 19 Javascript
react MPA 多页配置详解
Oct 18 Javascript
js实现圆形菜单选择器
Dec 03 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常用正则表达式的整理汇总
2013/06/08 PHP
PHP编程风格规范分享
2014/01/15 PHP
简单的php新闻发布系统教程
2014/05/09 PHP
PHP+sqlite数据库操作示例(创建/打开/插入/检索)
2016/05/26 PHP
使用PHP+Redis实现延迟任务,实现自动取消订单功能
2019/11/21 PHP
JavaScript DOM学习第一章 W3C DOM简介
2010/02/19 Javascript
js异步加载的三种解决方案
2013/03/04 Javascript
javascript中encodeURI和decodeURI方法使用介绍
2013/05/06 Javascript
固定网页背景图同时保持图片比例的思路代码
2013/08/15 Javascript
js 判断控件获得焦点的示例代码
2014/03/04 Javascript
同一个网页中实现多个JavaScript特效的方法
2015/02/02 Javascript
jquery让指定的元素闪烁显示的方法
2015/03/17 Javascript
JavaScript实现同时调用多个函数的方法
2015/11/09 Javascript
浅谈Javascript数组(推荐)
2016/05/17 Javascript
详解JavaScript数组过滤相同元素的5种方法
2017/05/23 Javascript
JavaScript之iterable_动力节点Java学院整理
2017/06/29 Javascript
让nodeJS支持ES6的词法----babel的安装和使用方法
2017/07/31 NodeJs
深入理解ES6的迭代器与生成器
2017/08/19 Javascript
[37:35]DOTA2上海特级锦标赛A组资格赛#1 Secret VS MVP.Phx第二局
2016/02/25 DOTA
基于Python实现的百度贴吧网络爬虫实例
2015/04/17 Python
最基础的Python的socket编程入门教程
2015/04/23 Python
python模拟表单提交登录图书馆
2018/04/27 Python
使用Python监视指定目录下文件变更的方法
2018/10/15 Python
python如何读取bin文件并下发串口
2019/07/05 Python
详解python statistics模块及函数用法
2019/10/27 Python
python 深度学习中的4种激活函数
2020/09/18 Python
比利时的在线灯具店:Lampen24.be
2019/07/01 全球购物
英国电气世界:Electrical World
2019/09/08 全球购物
实习生单位鉴定意见
2013/12/04 职场文书
俄罗斯商务邀请函
2014/01/26 职场文书
北京奥运会口号
2014/06/21 职场文书
上班迟到检讨书300字
2014/10/18 职场文书
网吧管理制度范本
2015/08/05 职场文书
2015新员工工作总结范文
2015/10/15 职场文书
2016银行招聘自荐信
2016/01/28 职场文书
前端canvas中物体边框和控制点的实现示例
2022/08/05 Javascript