当前位置:   article > 正文

原生JS封装拖动验证滑块你会吗?_原生js实现拖动滑块校验

原生js实现拖动滑块校验

前言

就想写个库玩玩

最终效果

分析

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

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

最终如何使用?

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

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

编写库的整体初始框架

  1. (function () {
  2. // =================代码块1=========================================
  3. var root = (typeof self == 'object' && self.self == self && self) ||
  4. (typeof global == 'object' && global.global == global && global) ||
  5. this || {};
  6. var util = {
  7. extend: function (target) {
  8. for (var i = 1, len = arguments.length; i < len; i++) {
  9. for (var prop in arguments[i]) {
  10. if (arguments[i].hasOwnProperty(prop)) {
  11. target[prop] = arguments[i][prop]
  12. }
  13. }
  14. }
  15. return target
  16. },
  17. isValidListener: function (listener) {
  18. if (typeof listener === 'function') {
  19. return true
  20. } else if (listener && typeof listener === 'object') {
  21. return util.isValidListener(listener.listener)
  22. } else {
  23. return false
  24. }
  25. },
  26. addCSS: function (cssText) {
  27. var style = document.createElement('style'), //创建一个style元素
  28. head = document.head || document.getElementsByTagName('head')[0]; //获取head元素
  29. style.type = 'text/css'; //这里必须显示设置style元素的type属性为text/css,否则在ie中不起作用
  30. if (style.styleSheet) { //IE
  31. var func = function () {
  32. try { //防止IE中stylesheet数量超过限制而发生错误
  33. style.styleSheet.cssText = cssText;
  34. } catch (e) {
  35. }
  36. }
  37. //如果当前styleSheet还不能用,则放到异步中则行
  38. if (style.styleSheet.disabled) {
  39. setTimeout(func, 10);
  40. } else {
  41. func();
  42. }
  43. } else { //w3c
  44. //w3c浏览器中只要创建文本节点插入到style元素中就行了
  45. var textNode = document.createTextNode(cssText);
  46. style.appendChild(textNode);
  47. }
  48. head.appendChild(style); //把创建的style元素插入到head中
  49. },
  50. indexOf: function (array, item) {
  51. if (array.indexOf) {
  52. return array.indexOf(item);
  53. } else {
  54. var result = -1;
  55. for (var i = 0, len = array.length; i < len; i++) {
  56. if (array[i] === item) {
  57. result = i;
  58. break;
  59. }
  60. }
  61. return result;
  62. }
  63. }
  64. }
  65. function EventEmitter() {
  66. this._events = {}
  67. }
  68. EventEmitter.prototype.on = function (eventName, listener) {
  69. if (!eventName || !listener) return;
  70. if (!util.isValidListener(listener)) {
  71. throw new TypeError('listener must be a function');
  72. }
  73. var events = this._events;
  74. var listeners = events[eventName] = events[eventName] || [];
  75. var listenerIsWrapped = typeof listener === 'object';
  76. // 不重复添加事件
  77. if (util.indexOf(listeners, listener) === -1) {
  78. listeners.push(listenerIsWrapped ? listener : {
  79. listener: listener,
  80. once: false
  81. });
  82. }
  83. return this;
  84. };
  85. EventEmitter.prototype.once = function (eventName, listener) {
  86. return this.on(eventName, {
  87. listener: listener,
  88. once: true
  89. })
  90. };
  91. EventEmitter.prototype.off = function (eventName, listener) {
  92. var listeners = this._events[eventName];
  93. if (!listeners) return;
  94. var index;
  95. for (var i = 0, len = listeners.length; i < len; i++) {
  96. if (listeners[i] && listeners[i].listener === listener) {
  97. index = i;
  98. break;
  99. }
  100. }
  101. if (typeof index !== 'undefined') {
  102. listeners.splice(index, 1, null)
  103. }
  104. return this;
  105. };
  106. EventEmitter.prototype.emit = function (eventName, args) {
  107. var listeners = this._events[eventName];
  108. if (!listeners) return;
  109. for (var i = 0; i < listeners.length; i++) {
  110. var listener = listeners[i];
  111. if (listener) {
  112. listener.listener.apply(this, args || []);
  113. if (listener.once) {
  114. this.off(eventName, listener.listener)
  115. }
  116. }
  117. }
  118. return this;
  119. };
  120. // =================代码块2=========================================
  121. function SliderTools(options) {
  122. this.options = util.extend({}, this.constructor.defaultOptions, options)
  123. this.init();
  124. this.bindEvents();
  125. this.diffX = 0;
  126. this.flag = false;//是否拖动到最右侧
  127. }
  128. SliderTools.defaultOptions = {
  129. el: document.body //默认放到body里
  130. };
  131. var proto = SliderTools.prototype = new EventEmitter();//SliderTools继承emitter
  132. proto.constructor = SliderTools;//修正构造器
  133. proto.init = function () {
  134. this.createSlider();//创建插件所需要的dom元素
  135. this.getElements();//获取创建好的元素
  136. }
  137. // =================代码块3=========================================
  138. if (typeof exports != 'undefined' && !exports.nodeType) {
  139. if (typeof module != 'undefined' && !module.nodeType && module.exports) {
  140. exports = module.exports = SliderTools;
  141. }
  142. exports.SliderTools = SliderTools;
  143. } else {
  144. root.SliderTools = SliderTools;
  145. }
  146. }());
  147. 复制代码

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

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

  1. proto.createSlider = function () {
  2. 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元素
  3. 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新的样式
  4. }
  5. proto.getElements = function () {
  6. this.slider = document.querySelector('#slider');
  7. this.drag_bg = document.querySelector('.drag_bg');
  8. this.handler = document.querySelector('.handler');
  9. }
  10. 复制代码

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

  1. proto.bindEvents = function () {
  2. var self = this;
  3. self.handler.onmousedown = function (e) {
  4. self.diffX = e.clientX - self.handler.offsetLeft;
  5. util.setClassName(self.slider, 'unselect'); //禁止选择样式
  6. document.onmousemove = function (e) {
  7. let deltaX = e.clientX - self.diffX;
  8. if (deltaX >= self.slider.offsetWidth - self.handler.offsetWidth) { //拖动到了最右侧
  9. deltaX = self.slider.offsetWidth - self.handler.offsetWidth;
  10. self.flag = true;
  11. } else if (deltaX <= 0) {
  12. deltaX = 0;
  13. self.flag = false;
  14. } else {
  15. self.flag = false;
  16. }
  17. util.setInlineStyle([self.handler], 'left', deltaX + 'px');
  18. util.setInlineStyle([self.drag_bg], 'width', deltaX + 'px');
  19. }
  20. document.onmouseup = function (e) {
  21. util.setClassName(self.slider, '')
  22. if (self.flag) {
  23. util.setClassName(self.slider, 'slide_ok') //拖动完成后的样式
  24. util.addClass(self.handler, 'handler_ok_bg')拖动完成后的样式
  25. self.handler.onmousedown = null //防止拖动完成后再次拖动
  26. self.emit('complete')//emit通知使用者的回调事件
  27. } else {
  28. util.setInlineStyle([self.handler], 'left', 0 + 'px');
  29. util.setInlineStyle([self.drag_bg], 'width', 0 + 'px');
  30. }
  31. document.onmousemove = null;
  32. document.onmouseup = null;
  33. }
  34. }
  35. }
  36. 复制代码

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

  1. var util = {
  2. // ...初始框架里的那部分
  3. setClassName(selector, className) {
  4. selector.className = className;
  5. },
  6. addClass(selector, className) {
  7. selector.classList.add(className);
  8. },
  9. setInlineStyle(selector, attr, content) {
  10. let length = selector.length;
  11. for (let i = 0; i < length; i++) {
  12. selector[i].style[attr] = content;
  13. }
  14. },
  15. }
  16. 复制代码

最终完整可运行代码

  1. (function () {
  2. var root = (typeof self == 'object' && self.self == self && self) ||
  3. (typeof global == 'object' && global.global == global && global) ||
  4. this || {};
  5. var util = {
  6. extend: function (target) {
  7. for (var i = 1, len = arguments.length; i < len; i++) {
  8. for (var prop in arguments[i]) {
  9. if (arguments[i].hasOwnProperty(prop)) {
  10. target[prop] = arguments[i][prop]
  11. }
  12. }
  13. }
  14. return target
  15. },
  16. setClassName(selector, className) {
  17. selector.className = className;
  18. },
  19. addClass(selector, className) {
  20. selector.classList.add(className);
  21. },
  22. setInlineStyle(selector, attr, content) {
  23. let length = selector.length;
  24. for (let i = 0; i < length; i++) {
  25. selector[i].style[attr] = content;
  26. }
  27. },
  28. isValidListener: function (listener) {
  29. if (typeof listener === 'function') {
  30. return true
  31. } else if (listener && typeof listener === 'object') {
  32. return util.isValidListener(listener.listener)
  33. } else {
  34. return false
  35. }
  36. },
  37. addCSS: function (cssText) {
  38. var style = document.createElement('style'), //创建一个style元素
  39. head = document.head || document.getElementsByTagName('head')[0]; //获取head元素
  40. style.type = 'text/css'; //这里必须显示设置style元素的type属性为text/css,否则在ie中不起作用
  41. if (style.styleSheet) { //IE
  42. var func = function () {
  43. try { //防止IE中stylesheet数量超过限制而发生错误
  44. style.styleSheet.cssText = cssText;
  45. } catch (e) {
  46. }
  47. }
  48. //如果当前styleSheet还不能用,则放到异步中则行
  49. if (style.styleSheet.disabled) {
  50. setTimeout(func, 10);
  51. } else {
  52. func();
  53. }
  54. } else { //w3c
  55. //w3c浏览器中只要创建文本节点插入到style元素中就行了
  56. var textNode = document.createTextNode(cssText);
  57. style.appendChild(textNode);
  58. }
  59. head.appendChild(style); //把创建的style元素插入到head中
  60. },
  61. indexOf: function (array, item) {
  62. if (array.indexOf) {
  63. return array.indexOf(item);
  64. } else {
  65. var result = -1;
  66. for (var i = 0, len = array.length; i < len; i++) {
  67. if (array[i] === item) {
  68. result = i;
  69. break;
  70. }
  71. }
  72. return result;
  73. }
  74. }
  75. }
  76. function EventEmitter() {
  77. this._events = {}
  78. }
  79. EventEmitter.prototype.on = function (eventName, listener) {
  80. if (!eventName || !listener) return;
  81. if (!util.isValidListener(listener)) {
  82. throw new TypeError('listener must be a function');
  83. }
  84. var events = this._events;
  85. var listeners = events[eventName] = events[eventName] || [];
  86. var listenerIsWrapped = typeof listener === 'object';
  87. // 不重复添加事件
  88. if (util.indexOf(listeners, listener) === -1) {
  89. listeners.push(listenerIsWrapped ? listener : {
  90. listener: listener,
  91. once: false
  92. });
  93. }
  94. return this;
  95. };
  96. EventEmitter.prototype.once = function (eventName, listener) {
  97. return this.on(eventName, {
  98. listener: listener,
  99. once: true
  100. })
  101. };
  102. EventEmitter.prototype.off = function (eventName, listener) {
  103. var listeners = this._events[eventName];
  104. if (!listeners) return;
  105. var index;
  106. for (var i = 0, len = listeners.length; i < len; i++) {
  107. if (listeners[i] && listeners[i].listener === listener) {
  108. index = i;
  109. break;
  110. }
  111. }
  112. if (typeof index !== 'undefined') {
  113. listeners.splice(index, 1, null)
  114. }
  115. return this;
  116. };
  117. EventEmitter.prototype.emit = function (eventName, args) {
  118. var listeners = this._events[eventName];
  119. if (!listeners) return;
  120. for (var i = 0; i < listeners.length; i++) {
  121. var listener = listeners[i];
  122. if (listener) {
  123. listener.listener.apply(this, args || []);
  124. if (listener.once) {
  125. this.off(eventName, listener.listener)
  126. }
  127. }
  128. }
  129. return this;
  130. };
  131. function SliderTools(options) {
  132. this.options = util.extend({}, this.constructor.defaultOptions, options)
  133. this.init();
  134. this.bindEvents();
  135. this.diffX = 0;
  136. this.flag = false;
  137. }
  138. SliderTools.VERSION = '1.0.0';
  139. SliderTools.defaultOptions = {
  140. el: document.body
  141. };
  142. var proto = SliderTools.prototype = new EventEmitter();
  143. proto.constructor = SliderTools;
  144. proto.init = function () {
  145. this.createSlider();
  146. this.getElements();
  147. }
  148. proto.createSlider = function () {
  149. 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>';
  150. 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; }')
  151. }
  152. proto.getElements = function () {
  153. this.slider = document.querySelector('#slider');
  154. this.drag_bg = document.querySelector('.drag_bg');
  155. this.handler = document.querySelector('.handler');
  156. }
  157. proto.bindEvents = function () {
  158. var self = this;
  159. self.handler.onmousedown = function (e) {
  160. self.diffX = e.clientX - self.handler.offsetLeft;
  161. util.setClassName(self.slider, 'unselect');
  162. document.onmousemove = function (e) {
  163. let deltaX = e.clientX - self.diffX;
  164. if (deltaX >= self.slider.offsetWidth - self.handler.offsetWidth) {
  165. deltaX = self.slider.offsetWidth - self.handler.offsetWidth;
  166. self.flag = true;
  167. } else if (deltaX <= 0) {
  168. deltaX = 0;
  169. self.flag = false;
  170. } else {
  171. self.flag = false;
  172. }
  173. util.setInlineStyle([self.handler], 'left', deltaX + 'px');
  174. util.setInlineStyle([self.drag_bg], 'width', deltaX + 'px');
  175. }
  176. document.onmouseup = function (e) {
  177. util.setClassName(self.slider, '')
  178. if (self.flag) {
  179. util.setClassName(self.slider, 'slide_ok')
  180. util.addClass(self.handler, 'handler_ok_bg')
  181. self.handler.onmousedown = null
  182. self.emit('complete')
  183. } else {
  184. util.setInlineStyle([self.handler], 'left', 0 + 'px');
  185. util.setInlineStyle([self.drag_bg], 'width', 0 + 'px');
  186. }
  187. document.onmousemove = null;
  188. document.onmouseup = null;
  189. }
  190. }
  191. }
  192. if (typeof exports != 'undefined' && !exports.nodeType) {
  193. if (typeof module != 'undefined' && !module.nodeType && module.exports) {
  194. exports = module.exports = SliderTools;
  195. }
  196. exports.SliderTools = SliderTools;
  197. } else {
  198. root.SliderTools = SliderTools;
  199. }
  200. }());
  201. let slider = new SliderTools();
  202. slider.on('complete',() => {
  203. alert('验证完成');
  204. })
  205. 复制代码

使用

  1. <script src="./SliderTools.js"></script>
  2. 复制代码

或者

  1. import SliderTools from './SliderTools.js'
  2. 复制代码

结语

完整源码地址: github.com/Dreams-d/Sl…


 转自掘金

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/748193
推荐阅读
相关标签
  

闽ICP备14008679号