"use strict"; (function ($) { /** * 去除单位转换成具体数据 * @param val * @returns 具体数据 */ function removeUnit(val) { if (typeof (val) == "number") { return val } else { var reg = /^(-)?\d+/g; return val.match(reg); } } /** * 具体数值与占比之间的转换(且限制范围) * @param val 需转换的数值(若为占比则不包括'%') * @param max 最大范围 * @param min 最小范围 * @param type 转换类型 "N":占比转换成具体数值 "P":具体数值转换成占比 * @returns "N"具体数值,或者"P"不含百分号的占比 NaN,代表type输入错误 */ function exchange(val, max, min, type) { // 保存转换数值 var result = NaN; switch (type) { // 具体数值 case "N": var res = Math.round((val / 100) * (max - min) + min); result = res < min ? min : res > max ? max : res; break; // 占比 case "P": var res = Math.round(((val - min) / (max - min)) * 100); result = res < 0 ? 0 : res > 100 ? 100 : res; break; } return result; } /** * Input可带单位的input框的点击拖拽进度 * @param Ele 实例this元素对象 * @param config 配置 */ function InputProgressBar(Ele, config) { //@ts-ignore this var _this = this; _this.config = { dragEle: "", clickEle: "", lbEle: "", lrEle: "", //scope: 200, scope: $(config.clickEle).parents(".sp-page").width(), max: 100, min: 0, unit: "", initVal: "", isShow: config.isShow, initValue: config.initValue//initValue为null时,没有限制;initValue不为null时,禁止所有小于initValue的操作(文本框输入,拖拽进度条,点击进度条) }; // 合并配置 _this.config = $.extend({}, _this.config, config); // 若拖拽的元素或者点击的元素不存在,则直接退出 if ($(_this.config.dragEle).length == 0 || $(_this.config.clickEle).length == 0 || $(_this.config.lbEle).length == 0 || $(_this.config.lrEle).length == 0) return; // 初始化 _this.init(Ele); // 绑定触发事件 _this.bind(); } /** * 初始 * Ele:绑定的input元素 */ InputProgressBar.prototype.init = function (Ele) { //@ts-ignore this var _this = this; // input元素 _this.inputEle = $(Ele); // 拖拽的元素 _this.dragEle = $(_this.config.dragEle); // 点击的元素 _this.clickEle = $(_this.config.clickEle); // 拖拽左侧背景元素 _this.lbEle = $(_this.config.lbEle); // 左右两侧背景元素 _this.lrEle = $(_this.config.lrEle); // 最大值显示元素 _this.maxEle = $("
", { class: "maxProgressBar" }).css({ right: 0, }); // 最小值显示元素 _this.minEle = $("", { class: "minProgressBar" }).css({ left: 0, }); _this.lrEle.css({ width: _this.config.scope + 18 + "px", height: "18px", position: "relative", top: "10px", left: 0, background: "#4DB64B", "border-radius": "9px", "z-index": 0, }) _this.clickEle.css({ width: _this.config.scope * (1 - _this.config.initValue / 100) + "px", height: "10px", position: "absolute", top: "4px", left: 9 + _this.config.scope * _this.config.initValue / 100 + "px", background: "#FDFDFD", "border-radius": "5px", cursor: "pointer", "z-index": 1, }); _this.dragEle.css({ position: "absolute", width: "20px", height: "20px", border:"1px solid #c3c3c3", "border-radius": "10px", background: "#5895C5", top: "50%", left: 0, "z-index": 5, transform: "translate(-50%, -50%)", }); _this.lbEle.css({ position: "absolute", width: 0, height: "10px", top: 0, left: "-1px", "z-index": 4, background: "#4DB64B", "border-radius": "5px", }); // 是否显示范围 if (_this.config.isShow) { _this.clickEle.append(_this.maxEle, _this.minEle); _this.maxEle.add(_this.minEle).css({ height: "20px", position: "absolute", top: "-20px", "line-height": "20px", "font-size": "12px", "text-align": "center", color: "#24211c", }); _this.minEle.html(_this.config.min + _this.config.unit); _this.maxEle.html(_this.config.max + _this.config.unit); } // 首次绑定数据 // 当前input数值 _this.nowVal = removeUnit(_this.config.initVal) || removeUnit(_this.inputEle.val()) || "0"; // 限制范围 _this.nowVal = _this.limits(Number(_this.nowVal)); // input显示 _this.inputEle.val(_this.nowVal + _this.config.unit); // 保存input初始值,用以后续输入错误处理 _this.initVal = _this.inputEle.val(); // 初次绑定 // 进度条占比 _this.percentage = exchange(_this.nowVal, _this.config.max, _this.config.min, "P"); _this.dragEle.css({ left: _this.config.initValue ? "0px" : (_this.config.scope * _this.percentage) / 100 + "px", }); _this.lbEle.css({ width: _this.config.initValue ? "0px" : (_this.config.scope * _this.percentage) / 100 + "px", }) _this.config.cb && _this.config.cb(_this.initVal); }; /** * 绑定触发事件 */ InputProgressBar.prototype.bind = function () { var doc = $(window.document); // @ts-ignore this var _this = this; /** * input框获取焦点事件 保存input初始值,用以后续输入错误处理 */ _this.bindEvent(_this.inputEle, "focus", function (event) { var e = event || window.event; _this.initVal = _this.inputEle.val(); _this.inputEle.select(); }); /** * input框按enter键 */ _this.bindEvent(_this.inputEle, "keydown", function (event) { var e = event || window.event; e.stopPropagation(); if (e.keyCode == 13) { _this.inputEle.blur(); } }); /** * input框失去焦点事件 */ _this.bindEvent(_this.inputEle, "blur", function (event) { var e = event || window.event; if (_this.inputEle.val() < _this.config.initValue) { _this.inputEle.val(_this.config.initValue) } var inVal = _this.inputEle.val() - _this.config.initValue; _this.handleInput(inVal); _this.config.cb && _this.config.cb(_this.initVal); }); /** * 点击的元素上的点击事件 */ _this.bindEvent(_this.clickEle, "click", function (event) { var e = event || window.event; e.stopPropagation(); e.preventDefault(); // 计算left值 var left = e.pageX - _this.clickEle.offset().left; // 限制当前进度范围 left = left < 0 ? 0 : left > _this.config.scope * (1 - _this.config.initValue / 100) ? _this.config.scope * (1 - _this.config.initValue / 100) : left; _this.dragEle.css({ left: left + "px", }); _this.lbEle.css({ width: left + "px", }) _this.percentage = (left / _this.config.scope) * 100; _this.nowVal = exchange(_this.percentage, _this.config.max, _this.config.min, "N"); _this.inputEle.val(_this.nowVal + _this.config.unit * 1 + _this.config.initValue); _this.initVal = _this.inputEle.val(); _this.config.cb && _this.config.cb(_this.initVal); }); /** * 拖拽的元素上的拖拽事件 */ _this.bindEvent(_this.dragEle, "mousedown", function () { /** * 鼠标移动 */ _this.bindEvent(doc, "mousemove", function (event) { var e = event || window.event; e.preventDefault(); //计算元素left值 var left = e.pageX - _this.clickEle.offset().left; // 限制当前进度范围 left = left < 0 ? 0 : left > _this.config.scope * (1 - _this.config.initValue / 100) ? _this.config.scope * (1 - _this.config.initValue / 100) : left; _this.dragEle.css({ left: left + "px", }); _this.lbEle.css({ width: left + "px", }) _this.percentage = (left / _this.config.scope) * 100; _this.nowVal = exchange(_this.percentage, _this.config.max, _this.config.min, "N"); _this.inputEle.val(_this.nowVal + _this.config.unit * 1 + _this.config.initValue); _this.initVal = _this.inputEle.val(); _this.config.cb && _this.config.cb(_this.initVal); }); /** * 鼠标抬起 */ _this.bindEvent(doc, "mouseup", function () { doc.off("mousemove"); //移除鼠标移动事件 }); }); }; /** * input框数值处理 * @param val:需处理的数值 */ InputProgressBar.prototype.handleInput = function (val) { // @ts-ignore this var _this = this; var resVal = removeUnit(val); if (resVal === null) { _this.inputEle.val(_this.initVal); } else { // input显示 _this.nowVal = _this.limits(Number(resVal)); _this.inputEle.val(_this.nowVal + _this.config.unit * 1 + _this.config.initValue); _this.initVal = _this.inputEle.val(); // 刷新当前进度 _this.percentage = exchange(_this.nowVal, _this.config.max, _this.config.min, "P"); _this.dragEle.css({ left: (_this.config.scope * _this.percentage) / 100 + "px", }); _this.lbEle.css({ width: (_this.config.scope * _this.percentage) / 100 + "px", }); } }; /** * 限制范围 * @param val:需限制数值 */ InputProgressBar.prototype.limits = function (val) { // @ts-ignore this var _this = this; var res = val < _this.config.min ? _this.config.min : val > _this.config.max ? _this.config.max : val; return res; }; /** * 修改绑定事件的回调函数的_this指向 * @param cb 回调函数 */ InputProgressBar.prototype.applyFun = function (cb) { // @ts-ignore this var _this = this; return function () { cb.apply(_this, Array.prototype.slice.call(arguments)); }; }; /** * 绑定事件 * @param Ele 绑定事件的元素 * @param event 绑定的事件名称 * @param cb 回调函数 */ InputProgressBar.prototype.bindEvent = function (Ele, event, cb) { // @ts-ignore this var _this = this; return Ele.on(event, _this.applyFun(cb)); }; /** * 绑定到jq原型链上 * @param config 配置 */ $.fn.inputProgressBar = function (config) { if (this.length !== 1) return; // @ts-ignore 绑定到jq原型链 return new InputProgressBar(this, config); }; // @ts-ignore 需引入jq })(jQuery);