直接放代码了, 纯 JS 在后面
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>range</title>
- <style>
- html {
- user-select: none;
- }
- .range-wrap {
- position: relative;
- margin: 50px;
- }
- .range-bar {
- width: 500px;
- height: 5px;
- border-radius: 5px;
- background: red;
- }
- .range-btn {
- width: 15px;
- height: 15px;
- border-radius: 50%;
- background: red;
- position: absolute;
- top: -5px;
- left: 0px;
- cursor: pointer;
- transition: left .1s;
- }
- .range-label {
- width: 50px;
- text-align: center;
- position: absolute;
- top: 10px;
- left: 0px;
- transform: translateX(-35%);
- transition: left .1s;
- }
- .range-disabled .range-bar,
- .range-disabled .range-btn {
- background: gray;
- }
- </style>
- </head>
- <body>
- <div class="range-wrap">
- <div class="range-bar"></div>
- <div class="range-btn"></div>
- <div class="range-label">0</div>
- </div>
- <div class="range-wrap range-wrap2">
- <div class="range-bar"></div>
- <div class="range-btn"></div>
- <div class="range-label">0</div>
- </div>
- <div class="range-wrap range-wrap3">
- <div class="range-bar"></div>
- <div class="range-btn"></div>
- <div class="range-label">0</div>
- </div>
- <!--<script src="./range.js"></script>-->
- <script>
- /**
- * 基本 DOM 结构要求, 样式和效果自定义
- * <div class="range-wrap">
- <div class="range-bar"></div>
- <div class="range-btn"></div>
- <div class="range-label"></div>
- </div>
- // 使用方法
- //1, 全部使用默认设置
- var myRange = new Range();
- // 方法
- myRange.disable(); // 禁用, 并给窗口加上一个 class range-disabled
- // myRange.reuse(); // 重用, 并移除上述 class
- myRange.setValue(200); // 手动修改值
- //2, 自定义参数
- var myRange2 = new Range({
- wrap: '.range-wrap2', // 指定容器唯一选择器, 默认为 range-wrap
- value: 1000, // 指定初始值
- max: 1500,
- min: 500,
- disabled: false // 是否禁止操作 - 禁用
- })
- //2, 传入回调函数, 自定义数值显示等操作
- var myRange3 = new Range({
- wrap: '.range-wrap3', // 指定容器唯一选择器
- callback: function (value) {
- this.label.innerHTML = '<mark>' + value + '个 </mark>'
- }
- })
- */
- (function () {
- var range = function (option) {
- if (option) {
- this.$wrap = option.wrap || '.range-wrap';
- this.value = option.value || 0;
- this.minValue = option.min || 0;
- this.maxValue = option.max || 100;
- this.disabled = option.disabled || false;
- this.callback = option.callback;
- }
- this.init();
- };
- range.prototype = {
- $wrap: '.range-wrap',
- mouseStart: 0,
- btnStart: 0,
- value: 0,
- minValue: 0,
- maxValue: 100,
- position: 0,
- disabled: false,
- barWidth: 0,
- init: function () {
- this.getElem();
- this.bindEvent();
- this.calcPositionByValue();
- },
- getElem: function () {
- var wrap = this.wrap = document.querySelector(this.$wrap);
- this.bar = wrap.querySelector('.range-bar');
- this.btn = wrap.querySelector('.range-btn');
- this.label = wrap.querySelector('.range-label');
- this.barWidth = this.btn.getBoundingClientRect().width;
- this.maxPosition = this.bar.getBoundingClientRect().width - (this.barWidth / 2);
- },
- bindEvent: function () {
- var me = this;
- me.btn.addEventListener('mousedown', function (e) {
- me.mouseStart = e.clientX;
- function move(e) {
- if (me.disabled === true) return;
- me.mousemove(e);
- }
- document.addEventListener('mousemove', move);
- document.addEventListener('mouseup', function up(e) {
- document.removeEventListener('mousemove', move);
- document.removeEventListener('mouseup', up);
- me.btnStart = me.position;
- });
- });
- me.bar.addEventListener('click', function (e) {
- if (me.disabled === true) return;
- me.clicked(e);
- });
- },
- clicked: function (e) {
- var x = e.offsetX;
- var current = x - (this.barWidth / 2);
- if (current <0) {
- current = 0;
- } else if (current> this.maxPosition) {
- current = this.maxPosition;
- }
- this.btnStart = this.position = current;
- this.move();
- },
- mousemove: function (e) {
- var x = e.clientX - this.mouseStart;
- var current = this.btnStart + x;
- if (current <0) {
- current = 0;
- } else if (current> this.maxPosition) {
- current = this.maxPosition;
- }
- this.position = current;
- this.move();
- },
- move() {
- var current = this.position;
- this.value = Math.round((this.position / this.maxPosition) * (this.maxValue - this.minValue)) + this.minValue;
- this.btn.style.left = (current + 'px');
- if (this.label) this.label.style.left = (current + 'px');
- if (!this.callback) {
- this.updateLable();
- } else {
- this.callback(this.value);
- }
- },
- calcPositionByValue: function () {
- var valuePercent = this.value / (this.maxValue + this.minValue);
- this.btnStart = this.position = this.maxPosition * valuePercent;
- this.move();
- },
- updateLable() {
- if (this.label) this.label.innerText = this.value;
- },
- setValue: function (val) {
- if (val> this.maxValue) {
- val = this.maxValue;
- } else if (val <this.minValue) {
- val = this.minValue;
- }
- this.value = val;
- this.calcPositionByValue();
- },
- disable: function () {
- if (this.disabled === false) {
- this.disabled = true;
- this.wrap.className += 'range-disabled';
- }
- return this;
- },
- reuse: function () {
- if (this.disabled === true) {
- this.disabled = false;
- this.wrap.className = this.wrap.className.replace('range-disabled', '');
- }
- return this;
- }
- };
- window.Range = range;
- })();
- </script>
- <script>
- // 使用方法
- //1, 全部使用默认设置
- var myRange = new Range();
- // 方法
- myRange.disable(); // 禁用, 并给窗口加上一个 class range-disabled
- // myRange.reuse(); // 重用, 并移除上述 class
- myRange.setValue(200); // 手动修改值
- //2, 自定义参数
- var myRange2 = new Range({
- wrap: '.range-wrap2', // 指定容器唯一选择器, 默认为 range-wrap
- value: 1000, // 指定初始值
- max: 1500,
- min: 500,
- disabled: false // 是否禁止操作 - 禁用
- })
- //2, 传入回调函数, 自定义数值显示等操作
- var myRange3 = new Range({
- wrap: '.range-wrap3', // 指定容器唯一选择器
- callback: function (value) {
- this.label.innerHTML = '<mark>' + value + '个 </mark>'
- }
- })
- </script>
- </body>
- </html>
js 代码
- /**
- * 基本 DOM 结构要求, 样式和效果自定义
- * <div class="range-wrap">
- <div class="range-bar"></div>
- <div class="range-btn"></div>
- <div class="range-label"></div>
- </div>
- // 使用方法
- //1, 全部使用默认设置
- var myRange = new Range();
- // 方法
- myRange.disable(); // 禁用, 并给窗口加上一个 class range-disabled
- // myRange.reuse(); // 重用, 并移除上述 class
- myRange.setValue(200); // 手动修改值
- //2, 自定义参数
- var myRange2 = new Range({
- wrap: '.range-wrap2', // 指定容器唯一选择器, 默认为 range-wrap
- value: 1000, // 指定初始值
- max: 1500,
- min: 500,
- disabled: false // 是否禁止操作 - 禁用
- })
- //2, 传入回调函数, 自定义数值显示等操作
- var myRange3 = new Range({
- wrap: '.range-wrap3', // 指定容器唯一选择器
- callback: function (value) {
- this.label.innerHTML = '<mark>' + value + '个 </mark>'
- }
- })
- */
- (function () {
- var range = function (option) {
- if (option) {
- this.$wrap = option.wrap || '.range-wrap';
- this.value = option.value || 0;
- this.minValue = option.min || 0;
- this.maxValue = option.max || 100;
- this.disabled = option.disabled || false;
- this.callback = option.callback;
- }
- this.init();
- };
- range.prototype = {
- $wrap: '.range-wrap',
- mouseStart: 0,
- btnStart: 0,
- value: 0,
- minValue: 0,
- maxValue: 100,
- position: 0,
- disabled: false,
- barWidth: 0,
- init: function () {
- this.getElem();
- this.bindEvent();
- this.calcPositionByValue();
- },
- getElem: function () {
- var wrap = this.wrap = document.querySelector(this.$wrap);
- this.bar = wrap.querySelector('.range-bar');
- this.btn = wrap.querySelector('.range-btn');
- this.label = wrap.querySelector('.range-label');
- this.barWidth = this.btn.getBoundingClientRect().width;
- this.maxPosition = this.bar.getBoundingClientRect().width - (this.barWidth / 2);
- },
- bindEvent: function () {
- var me = this;
- me.btn.addEventListener('mousedown', function (e) {
- me.mouseStart = e.clientX;
- function move(e) {
- if (me.disabled === true) return;
- me.mousemove(e);
- }
- document.addEventListener('mousemove', move);
- document.addEventListener('mouseup', function up(e) {
- document.removeEventListener('mousemove', move);
- document.removeEventListener('mouseup', up);
- me.btnStart = me.position;
- });
- });
- me.bar.addEventListener('click', function (e) {
- if (me.disabled === true) return;
- me.clicked(e);
- });
- },
- clicked: function (e) {
- var x = e.offsetX;
- var current = x - (this.barWidth / 2);
- if (current <0) {
- current = 0;
- } else if (current> this.maxPosition) {
- current = this.maxPosition;
- }
- this.btnStart = this.position = current;
- this.move();
- },
- mousemove: function (e) {
- var x = e.clientX - this.mouseStart;
- var current = this.btnStart + x;
- if (current <0) {
- current = 0;
- } else if (current> this.maxPosition) {
- current = this.maxPosition;
- }
- this.position = current;
- this.move();
- },
- move() {
- var current = this.position;
- this.value = Math.round((this.position / this.maxPosition) * (this.maxValue - this.minValue)) + this.minValue;
- this.btn.style.left = (current + 'px');
- if (this.label) this.label.style.left = (current + 'px');
- if (!this.callback) {
- this.updateLable();
- } else {
- this.callback(this.value);
- }
- },
- calcPositionByValue: function () {
- var valuePercent = this.value / (this.maxValue + this.minValue);
- this.btnStart = this.position = this.maxPosition * valuePercent;
- this.move();
- },
- updateLable() {
- if (this.label) this.label.innerText = this.value;
- },
- setValue: function (val) {
- if (val> this.maxValue) {
- val = this.maxValue;
- } else if (val < this.minValue) {
- val = this.minValue;
- }
- this.value = val;
- this.calcPositionByValue();
- },
- disable: function () {
- if (this.disabled === false) {
- this.disabled = true;
- this.wrap.className += 'range-disabled';
- }
- return this;
- },
- reuse: function () {
- if (this.disabled === true) {
- this.disabled = false;
- this.wrap.className = this.wrap.className.replace('range-disabled', '');
- }
- return this;
- }
- };
- window.Range = range;
- })();
来源: http://www.qdfuns.com/article/17085/af9373878cef804fe40c68c495a89936.html