原生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 相关文章推荐
Mootools 1.2教程 滑动效果(Slide)
Sep 15 Javascript
javascript中最常用的继承模式 组合继承
Aug 12 Javascript
innerHTML,outerHTML,innerText,outerText的用法及区别解析
Dec 16 Javascript
Node.js实现简单聊天服务器
Jun 20 Javascript
JavaScript极简入门教程(二):对象和函数
Oct 25 Javascript
js简单实现Select互换数据的方法
Aug 17 Javascript
利用Angular.js限制textarea输入的字数
Oct 20 Javascript
微信小程序云开发之数据库操作
May 18 Javascript
关于layui表单中按钮自动提交的解决方法
Sep 09 Javascript
vue 将多个过滤器封装到一个文件中的代码详解
Sep 05 Javascript
nuxt 服务器渲染动态设置 title和seo关键字的操作
Nov 05 Javascript
React更新渲染原理深入分析
Dec 24 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作为Shell脚本语言使用
2006/10/09 PHP
php5 pdo新改动加载注意事项
2008/09/11 PHP
PHP strtotime函数详解
2009/12/18 PHP
PHP 飞信好友免费短信API接口开源版
2010/07/22 PHP
PHP学习之数组值的操作
2011/04/17 PHP
基于curl数据采集之单页面并行采集函数get_htmls的使用
2013/04/28 PHP
php常用图片处理类
2016/03/16 PHP
PHP在同一域名下两个不同的项目做独立登录机制详解
2017/09/22 PHP
javscript对象原型的一些看法
2010/09/19 Javascript
jquery 学习之二 属性 文本与值(text,val)
2010/11/25 Javascript
javascript 日期时间 转换的方法
2013/02/21 Javascript
JavaScript验证电子邮箱的函数
2014/08/22 Javascript
分享20个提升网站界面体验的jQuery插件
2014/12/15 Javascript
基于JavaScript实现TAB标签效果
2016/01/12 Javascript
jQuery+ajax+asp.net获取Json值的方法
2016/06/08 Javascript
微信小程序网络请求wx.request详解及实例
2017/05/18 Javascript
vue.js实现格式化时间并每秒更新显示功能示例
2018/07/07 Javascript
微信小程序实现左侧滑动导航栏
2020/04/08 Javascript
Python中解析JSON并同时进行自定义编码处理实例
2015/02/08 Python
Python实现合并字典的方法
2015/07/07 Python
python开发之thread线程基础实例入门
2015/11/11 Python
python实现简单爬虫功能的示例
2016/10/24 Python
Python多维/嵌套字典数据无限遍历的实现
2016/11/04 Python
Python数据类型中的“冒号“[::]——分片与步长操作示例
2018/01/24 Python
python入门前的第一课 python怎样入门
2018/03/06 Python
numpy.linalg.eig() 计算矩阵特征向量方式
2019/11/29 Python
python使用自定义钉钉机器人的示例代码
2020/06/24 Python
python爬虫调度器用法及实例代码
2020/11/30 Python
蹦床仓库:Trampoline Warehouse
2018/12/06 全球购物
英国领先的在线高尔夫商店:Gamola Golf
2019/11/16 全球购物
德国旅行、体验和活动的预订平台:Watado
2019/12/04 全球购物
丝芙兰墨西哥官网:Sephora墨西哥
2020/05/30 全球购物
《特殊的葬礼》教学反思
2014/04/27 职场文书
商场广播稿范文
2015/08/19 职场文书
《妈妈别哭,有我在》读后感3篇
2020/01/13 职场文书
RPM包方式安装Oracle21c的方法详解
2021/08/23 Oracle