rangeable
Advanced tools
Comparing version 0.0.11 to 0.1.0
@@ -1,10 +0,11 @@ | ||
/* | ||
Rangeable | ||
Copyright (c) 2018 Karl Saunders | ||
Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) | ||
and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. | ||
Version: 0.0.11 | ||
*/ | ||
var Rangeable=function(h,i){"string"==typeof h&&(h=document.querySelector(h)),this.input=h,this.config=Object.assign({},{type:"single",tooltips:"always",classes:{input:"rangeable-input",container:"rangeable-container",vertical:"rangeable-vertical",progress:"rangeable-progress",handle:"rangeable-handle",tooltip:"rangeable-tooltip",track:"rangeable-track",multiple:"rangeable-multiple",disabled:"rangeable-disabled"}},i),this.mouseAxis={x:"clientX",y:"clientY"},this.trackSize={x:"width",y:"height"},this.trackPos={x:"left",y:"top"},this.lastPos=0,this.double="double"===this.config.type||Array.isArray(this.config.value),this.touch="ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch,this.init(),this.onInit()};Rangeable.prototype.init=function(){if(!this.input.rangeable){var i,h={min:0,max:100,step:1,value:this.input.value};for(i in h)this.input[i]||(this.input[i]=h[i]),void 0!==this.config[i]&&(this.input[i]=this.config[i]);this.axis=this.config.vertical?"y":"x",this.input.rangeable=this,this.double?(this.input.values=this.config.value?this.config.value:[this.input.min,this.input.max],this.input.defaultValues=this.input.values.slice()):this.input.defaultValue||(this.input.defaultValue=this.input.value),this.render(),this.initialised=!0}},Rangeable.prototype.render=function(){var h=this.config,i=h.classes,j=this.createElement("div",i.container),k=this.createElement("div",i.track),l=this.createElement("div",i.progress),m=this.createElement("div",i.handle),n=this.createElement("div",i.tooltip);k.appendChild(l),this.double?(m=[this.createElement("div",i.handle),this.createElement("div",i.handle)],n=[this.createElement("div",i.tooltip),this.createElement("div",i.tooltip),this.createElement("div",i.tooltip)],m.forEach(function(o,p){o.index=p,l.appendChild(o),o.appendChild(n[p]),o.tabIndex=1}),this.input.tabIndex=-1,h.vertical&&l.appendChild(m[0]),l.appendChild(n[2]),j.classList.add(i.multiple)):(l.appendChild(m),m.appendChild(n)),this.nodes={container:j,track:k,progress:l,handle:m,tooltip:n},j.appendChild(k),h.vertical&&j.classList.add(i.vertical),h.size&&(j.style[this.trackSize[this.axis]]=isNaN(h.size)?h.size:h.size+"px"),h.tooltips&&(j.classList.add("has-tooltip"),"string"==typeof h.tooltips&&"always"===h.tooltips&&j.classList.add("show-tooltip")),this.input.parentNode.insertBefore(j,this.input),j.insertBefore(this.input,k),this.input.classList.add(i.input),this.bind(),this.update()},Rangeable.prototype.reset=function(){this.double?this.input.defaultValues.forEach(this.setValue,this):this.setValue(this.input.defaultValue),this.onEnd()},Rangeable.prototype.setValueFromPosition=function(h){var i=parseFloat(this.input.min),j=parseFloat(this.input.max),k=parseFloat(this.input.step),l=this.touch?h.touches[0][this.mouseAxis[this.axis]]:h[this.mouseAxis[this.axis]],m=l-this.rects.container[this.trackPos[this.axis]],n=this.rects.container[this.trackSize[this.axis]];return"mousedown"===h.type&&(!this.double&&this.nodes.handle.contains(h.target)||this.double&&(this.nodes.handle[0].contains(h.target)||this.nodes.handle[1].contains(h.target)))?!1:(h=Math.ceil(((this.config.vertical?100*((n-m)/n):100*(m/n))*(j-i)/100+i)/k)*k,l>=this.lastPos&&(h-=k),parseFloat(h)!==parseFloat(this.startValue)&&void(k=!1,this.double&&(k=this.activeHandle.index,!k&&h>=this.input.values[1]?h=this.input.values[1]:k&&h<=this.input.values[0]&&(h=this.input.values[0])),this.setValue(h,k)))},Rangeable.prototype.start=function(h){h.preventDefault(),this.startValue=this.getValue(),this.onStart(),this.nodes.container.classList.add("dragging"),this.recalculate(),this.activeHandle=this.getHandle(h),this.activeHandle.classList.add("active"),this.setValueFromPosition(h),this.touch?(document.addEventListener("touchmove",this.events.move,!1),document.addEventListener("touchend",this.events.stop,!1),document.addEventListener("touchcancel",this.events.stop,!1)):(document.addEventListener("mousemove",this.events.move,!1),document.addEventListener("mouseup",this.events.stop,!1))},Rangeable.prototype.move=function(h){this.setValueFromPosition(h),this.lastPos=this.touch?h.touches[0][this.mouseAxis[this.axis]]:h[this.mouseAxis[this.axis]]},Rangeable.prototype.stop=function(){this.stopValue=this.getValue(),this.nodes.container.classList.remove("dragging"),this.onEnd(),this.activeHandle.classList.remove("active"),this.activeHandle=!1,document.removeEventListener("mousemove",this.events.move),document.removeEventListener("mouseup",this.events.stop),document.removeEventListener("touchmove",this.events.move),document.removeEventListener("touchend",this.events.stop),document.removeEventListener("touchcancel",this.events.stop),this.startValue!==this.stopValue&&this.input.dispatchEvent(new Event("change")),this.startValue=null},Rangeable.prototype.keydown=function(h){var i=this;this.double&&this.nodes.handle.forEach(function(j){if(j===document.activeElement)switch(h.key){case"ArrowRight":case"ArrowUp":i.stepUp(j.index);break;case"ArrowLeft":case"ArrowDown":i.stepDown(j.index);}})},Rangeable.prototype.stepUp=function(h){var i=parseFloat(this.input.step),j=this.getValue();this.double&&void 0!==h&&(j=j[h]),i=this.limit(parseFloat(j)+i,h),this.setValue(i,h)},Rangeable.prototype.stepDown=function(h){var i=parseFloat(this.input.step),j=this.getValue();this.double&&void 0!==h&&(j=j[h]),i=this.limit(parseFloat(j)-i,h),this.setValue(i,h)},Rangeable.prototype.limit=function(h,i){var j=this.input,k=parseFloat(j.min),l=parseFloat(j.max);return this.getValue(),this.double&&void 0!==i&&(!i&&h>=j.values[1]?h=j.values[1]:i&&h<=j.values[0]&&(h=j.values[0])),h>=l?h=l:h<=k&&(h=k),h},Rangeable.prototype.recalculate=function(){var h=[];this.double?this.nodes.handle.forEach(function(i,j){h[j]=i.getBoundingClientRect()}):h=this.nodes.handle.getBoundingClientRect(),this.rects={handle:h,container:this.nodes.container.getBoundingClientRect()}},Rangeable.prototype.update=function(){var h=this;this.recalculate(),this.accuracy=0,this.input.step.includes(".")&&(this.accuracy=(this.input.step.split(".")[1]||[]).length),this.double?this.input.values.forEach(function(i,j){h.setValue(i,j)}):this.setValue()},Rangeable.prototype.getValue=function(){return this.double?this.input.values:this.input.value},Rangeable.prototype.parseValue=function(h){var i=parseFloat(this.input.min),j=parseFloat(this.input.max);return void 0===h&&(h=this.input.value),h=parseFloat(h),h=h.toFixed(this.accuracy),h<i?h=i.toFixed(this.accuracy):h>j&&(h=j.toFixed(this.accuracy)),h},Rangeable.prototype.setValue=function(h,i){var j=this.nodes;if(h=this.parseValue(h),this.double&&void 0===i)return!1;var k=this.initialised&&(h!==this.input.value||this.nativeEvent);if(this.double){var l=this.input.values;if(l[i]=h,this.config.tooltips){j.tooltip[i].textContent=h;var m=j.tooltip[0].getBoundingClientRect(),n=j.tooltip[1].getBoundingClientRect();m=!(m.right<n.left||m.left>n.right||m.bottom<n.top||m.top>n.bottom),j.container.classList.toggle("combined-tooltip",m),m&&(j.tooltip[2].textContent=l[0]===l[1]?l[0]:l[0]+" - "+l[1])}}else this.input.value=h,j.tooltip.textContent=h;this.setPosition(h,i),k&&(this.onChange(),this.nativeEvent||this.input.dispatchEvent(new Event("input")),this.nativeEvent=!1)},Rangeable.prototype.native=function(){this.nativeEvent=!0,this.setValue()},Rangeable.prototype.setPosition=function(h){if(this.double){h=this.getPosition(this.input.values[0]);var i=this.getPosition(this.input.values[1]);this.nodes.progress.style[this.config.vertical?"bottom":"left"]=h+"px",h=i-h}else h=this.getPosition();this.nodes.progress.style[this.trackSize[this.axis]]=h+"px"},Rangeable.prototype.getPosition=function(h){h=void 0===h?this.input.value:h;var i=parseFloat(this.input.min),j=parseFloat(this.input.max);return(h-i)/(j-i)*this.rects.container[this.trackSize[this.axis]]},Rangeable.prototype.getHandle=function(h){if(!this.double)return this.nodes.handle;var i=this.rects,j=Math.abs(h[this.mouseAxis[this.axis]]-i.handle[0][this.trackPos[this.axis]]);return i=Math.abs(h[this.mouseAxis[this.axis]]-i.handle[1][this.trackPos[this.axis]]),(h=h.target.closest("."+this.config.classes.handle))?h:j>i?this.nodes.handle[1]:this.nodes.handle[0]},Rangeable.prototype.onInit=function(){this.isFunction(this.config.onInit)&&this.config.onInit.call(this,this.getValue())},Rangeable.prototype.onStart=function(){this.isFunction(this.config.onStart)&&this.config.onStart.call(this,this.getValue())},Rangeable.prototype.onChange=function(){this.isFunction(this.config.onChange)&&this.config.onChange.call(this,this.getValue())},Rangeable.prototype.onEnd=function(){this.isFunction(this.config.onEnd)&&this.config.onEnd.call(this,this.getValue())},Rangeable.prototype.enable=function(){this.disabled&&(this.touch?this.nodes.container.addEventListener("touchstart",this.events.touchstart,!1):this.nodes.container.addEventListener("mousedown",this.events.down),this.nodes.container.classList.remove(this.config.classes.disabled),this.disabled=!1)},Rangeable.prototype.disable=function(){this.disabled||(this.touch?this.nodes.container.removeEventListener("touchstart",this.events.touchstart):this.nodes.container.removeEventListener("mousedown",this.events.down),this.nodes.container.classList.add(this.config.classes.disabled),this.disabled=!0)},Rangeable.prototype.bind=function(){this.events={start:this.start.bind(this),move:this.move.bind(this),stop:this.stop.bind(this),update:this.update.bind(this),reset:this.reset.bind(this),set:this.native.bind(this),key:this.keydown.bind(this)},this.events.scroll=this.throttle(this.events.update,100),this.events.resize=this.throttle(this.events.update,50),document.addEventListener("scroll",this.events.scroll,!1),window.addEventListener("resize",this.events.resize,!1),this.double&&document.addEventListener("keydown",this.events.key,!1),this.nodes.container.addEventListener(this.touch?"touchstart":"mousedown",this.events.start,!1),this.input.addEventListener("input",this.events.set),this.input.form&&this.input.form.addEventListener("reset",this.events.reset,!1)},Rangeable.prototype.unbind=function(){document.removeEventListener("scroll",this.events.scroll),window.removeEventListener("resize",this.events.resize),this.double&&document.removeEventListener("keydown",this.events.key),this.nodes.container.removeEventListener(this.touch?"touchstart":"mousedown",this.events.start),this.input.removeEventListener("input",this.events.set),this.input.form&&this.input.form.removeEventListener("reset",this.events.reset),this.events=null},Rangeable.prototype.destroy=function(){this.input.rangeable&&(this.unbind(),this.input.classList.remove(this.config.classes.input),this.nodes.container.parentNode.replaceChild(this.input,this.nodes.container),delete this.input.rangeable,this.initialised=!1)},Rangeable.prototype.createElement=function(h,i){var j=document.createElement(h);return i&&j.classList.add(i),j},Rangeable.prototype.isFunction=function(h){return h&&"function"==typeof h},Rangeable.prototype.throttle=function(h,i,j){var k;return function(){if(j=j||this,!k)return h.apply(j,arguments),k=!0,setTimeout(function(){k=!1},i)}}; | ||
/*! | ||
* | ||
* Rangeable | ||
* Copyright (c) 2018 Karl Saunders (mobius1(at)gmx(dot)com) | ||
* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) | ||
* and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. | ||
* | ||
* Version: 0.1.0 | ||
* | ||
*/ | ||
(function(i,j){"object"==typeof exports?module.exports=j("Rangeable"):"function"==typeof define&&define.amd?define([],j):i.Rangeable=j("Rangeable")})("undefined"==typeof global?this.window||this.global:global,function(){var i=function(o,p){var q=document.createElement(o);return p&&q.classList.add(p),q},j=function(o){return o&&"function"==typeof o},m=function(o,p,q){var r;return function(){if(q=q||this,!r)return o.apply(q,arguments),r=!0,setTimeout(function(){r=!1},p)}},n=function(o,p){this.plugins=["ruler"],"string"==typeof o&&(o=document.querySelector(o)),this.input=o,this.config=Object.assign({},{type:"single",tooltips:"always",updateThrottle:30,classes:{input:"rangeable-input",container:"rangeable-container",vertical:"rangeable-vertical",progress:"rangeable-progress",handle:"rangeable-handle",tooltip:"rangeable-tooltip",track:"rangeable-track",multiple:"rangeable-multiple",disabled:"rangeable-disabled"}},p),this.mouseAxis={x:"clientX",y:"clientY"},this.trackSize={x:"width",y:"height"},this.trackPos={x:"left",y:"top"},this.lastPos=0,this.double="double"===this.config.type||Array.isArray(this.config.value),this.touch="ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch,this.init(),this.onInit()};return n.prototype.init=function(){if(!this.input.rangeable){var p,o={min:0,max:100,step:1,value:this.input.value};for(p in o)this.input[p]||(this.input[p]=o[p]),void 0!==this.config[p]&&(this.input[p]=this.config[p]);this.axis=this.config.vertical?"y":"x",this.input.rangeable=this,this.double?(this.input.values=this.config.value?this.config.value:[this.input.min,this.input.max],this.input.defaultValues=this.input.values.slice()):this.input.defaultValue||(this.input.defaultValue=this.input.value),this.render(),this.initialised=!0}},n.prototype.render=function(){var o=this,p=this.config,q=p.classes,r=i("div",q.container),s=i("div",q.track),t=i("div",q.progress),u=i("div",q.handle),v=i("div",q.tooltip);if(this.double?(u=[i("div",q.handle),i("div",q.handle)],v=[i("div",q.tooltip),i("div",q.tooltip),i("div",q.tooltip)],u.forEach(function(x,y){x.index=y,t.appendChild(x),x.appendChild(v[y]),x.tabIndex=1,p.handles&&p.handles[y]&&p.handles[y].locked&&!0===p.handles[y].locked&&(x.locked=!0)}),this.input.tabIndex=-1,p.vertical&&t.appendChild(u[0]),t.appendChild(v[2]),r.classList.add(q.multiple)):(t.appendChild(u),u.appendChild(v),p.handle&&p.handle.locked&&!0===p.handle.locked&&(u.locked=!0)),r.appendChild(s),p.vertical&&r.classList.add(q.vertical),p.size&&(r.style[this.trackSize[this.axis]]=isNaN(p.size)?p.size:p.size+"px"),p.tooltips&&(r.classList.add("has-tooltip"),"string"==typeof p.tooltips&&"always"===p.tooltips&&r.classList.add("show-tooltip")),this.nodes={container:r,track:s,progress:t,handle:u,tooltip:v},!this.double)p.handle&&void 0!==p.handle.min&&void 0!==p.handle.max&&(u=i("div","rangeable-buffer"),s.appendChild(u),this.nodes.buffer=u,this.limits={min:p.handle.min,max:p.handle.max});else if(p.handles){this.nodes.buffers=[],this.limits=[];var w=i("div","rangeable-buffers");p.handles.forEach(function(x,y){if(void 0!==x.min&&void 0!==x.max){var z=i("div","rangeable-buffer");w.appendChild(z),o.nodes.buffers.push(z),o.limits[y]={min:x.min,max:x.max}}}),s.appendChild(w)}s.appendChild(t),this.input.parentNode.insertBefore(r,this.input),r.insertBefore(this.input,s),this.input.classList.add(q.input),this.bind(),this.update()},n.prototype.reset=function(){this.double?this.input.defaultValues.forEach(this.setValue,this):this.setValue(this.input.defaultValue),this.onEnd()},n.prototype.setValueFromPosition=function(o){var p=parseFloat(this.input.min),q=parseFloat(this.input.max),r=parseFloat(this.input.step),s=this.touch?o.touches[0][this.mouseAxis[this.axis]]:o[this.mouseAxis[this.axis]],t=s-this.rects.container[this.trackPos[this.axis]],u=this.rects.container[this.trackSize[this.axis]];return"mousedown"===o.type&&(!this.double&&this.nodes.handle.contains(o.target)||this.double&&(this.nodes.handle[0].contains(o.target)||this.nodes.handle[1].contains(o.target)))?!1:(o=Math.ceil(((this.config.vertical?100*((u-t)/u):100*(t/u))*(q-p)/100+p)/r)*r,s>=this.lastPos&&(o-=r),parseFloat(o)!==parseFloat(this.startValue)&&void(r=!1,this.double&&(r=this.activeHandle.index),o=this.limit(o,r),this.setValue(o,r)))},n.prototype.start=function(o){return o.preventDefault(),this.startValue=this.getValue(),this.onStart(),this.nodes.container.classList.add("dragging"),this.recalculate(),this.activeHandle=this.getHandle(o),!!this.activeHandle&&void(this.activeHandle.classList.add("active"),this.setValueFromPosition(o),this.touch?(document.addEventListener("touchmove",this.events.move,!1),document.addEventListener("touchend",this.events.stop,!1),document.addEventListener("touchcancel",this.events.stop,!1)):(document.addEventListener("mousemove",this.events.move,!1),document.addEventListener("mouseup",this.events.stop,!1)))},n.prototype.move=function(o){this.setValueFromPosition(o),this.lastPos=this.touch?o.touches[0][this.mouseAxis[this.axis]]:o[this.mouseAxis[this.axis]]},n.prototype.stop=function(){this.stopValue=this.getValue(),this.nodes.container.classList.remove("dragging"),this.onEnd(),this.activeHandle.classList.remove("active"),this.activeHandle=!1,this.touch?(document.removeEventListener("touchmove",this.events.move),document.removeEventListener("touchend",this.events.stop),document.removeEventListener("touchcancel",this.events.stop)):(document.removeEventListener("mousemove",this.events.move),document.removeEventListener("mouseup",this.events.stop)),this.startValue!==this.stopValue&&this.input.dispatchEvent(new Event("change")),this.startValue=null},n.prototype.keydown=function(o){var p=this;this.double&&this.nodes.handle.forEach(function(q){if(q===document.activeElement)switch(o.key){case"ArrowRight":case"ArrowUp":p.stepUp(q.index);break;case"ArrowLeft":case"ArrowDown":p.stepDown(q.index);}})},n.prototype.stepUp=function(o){var p=parseFloat(this.input.step),q=this.getValue();this.double&&void 0!==o&&(q=q[o]),p=this.limit(parseFloat(q)+p,o),this.setValue(p,o)},n.prototype.stepDown=function(o){var p=parseFloat(this.input.step),q=this.getValue();this.double&&void 0!==o&&(q=q[o]),p=this.limit(parseFloat(q)-p,o),this.setValue(p,o)},n.prototype.limit=function(o,p){var q=this.input,r=parseFloat(q.min),s=parseFloat(q.max);return this.getValue(),this.double&&void 0!==p?(!p&&o>=q.values[1]?o=q.values[1]:p&&o<=q.values[0]&&(o=q.values[0]),this.limits)&&(p?o>this.limits[1].max?o=this.limits[1].max:o<this.limits[1].min&&(o=this.limits[1].min):o>this.limits[0].max?o=this.limits[0].max:o<this.limits[0].min&&(o=this.limits[0].min)):this.limits&&(o>this.limits.max?o=this.limits.max:o<this.limits.min&&(o=this.limits.min)),o>=s?o=s:o<=r&&(o=r),o},n.prototype.recalculate=function(){var o=[];this.double?this.nodes.handle.forEach(function(p,q){o[q]=p.getBoundingClientRect()}):o=this.nodes.handle.getBoundingClientRect(),this.rects={handle:o,container:this.nodes.container.getBoundingClientRect()}},n.prototype.update=function(){var o=this;this.recalculate(),this.accuracy=0,this.input.step.includes(".")&&(this.accuracy=(this.input.step.split(".")[1]||[]).length);var p=this.rects.container[this.trackSize[this.axis]];if(this.double)this.config.handles&&this.nodes.buffers&&this.config.handles.forEach(function(s,t){var u=o.nodes.buffers[t],v=s.min/o.input.max*p;u.style[o.config.vertical?"bottom":"left"]=v+"px",u.style[o.trackSize[o.axis]]=s.max/o.input.max*p-v+"px"});else if(this.config.handle){var q=this.nodes.buffer,r=this.config.handle.min/this.input.max*p;q.style.left=r+"px",q.style.width=this.config.handle.max/this.input.max*p-r+"px"}q=this.getValue(),this.double?this.input.values.forEach(function(s,t){o.setValue(o.limit(s,t),t)}):this.setValue(this.limit(q))},n.prototype.getValue=function(){return this.double?this.input.values:this.input.value},n.prototype.parseValue=function(o){var p=parseFloat(this.input.min),q=parseFloat(this.input.max);return void 0===o&&(o=this.input.value),o=parseFloat(o),o=o.toFixed(this.accuracy),o<p?o=p.toFixed(this.accuracy):o>q&&(o=q.toFixed(this.accuracy)),o},n.prototype.setValue=function(o,p){var q=this.nodes;if(o=this.parseValue(o),this.double&&void 0===p)return!1;var r=this.initialised&&(o!==this.input.value||this.nativeEvent);if(this.double){var s=this.input.values;if(s[p]=o,this.config.tooltips){q.tooltip[p].textContent=o;var t=q.tooltip[0].getBoundingClientRect(),u=q.tooltip[1].getBoundingClientRect();t=!(t.right<u.left||t.left>u.right||t.bottom<u.top||t.top>u.bottom),q.container.classList.toggle("combined-tooltip",t),t&&(q.tooltip[2].textContent=s[0]===s[1]?s[0]:s[0]+" - "+s[1])}}else this.input.value=o,q.tooltip.textContent=o;this.setPosition(o,p),r&&(this.onChange(),this.nativeEvent||this.input.dispatchEvent(new Event("input")),this.nativeEvent=!1)},n.prototype.native=function(){this.nativeEvent=!0,this.setValue()},n.prototype.setPosition=function(o){if(this.double){o=this.getPosition(this.input.values[0]);var p=this.getPosition(this.input.values[1]);this.nodes.progress.style[this.config.vertical?"bottom":"left"]=o+"px",o=p-o}else o=this.getPosition();this.nodes.progress.style[this.trackSize[this.axis]]=o+"px"},n.prototype.getPosition=function(o){void 0===o&&(o=this.input.value);var p=parseFloat(this.input.min),q=parseFloat(this.input.max);return(o-p)/(q-p)*this.rects.container[this.trackSize[this.axis]]},n.prototype.getHandle=function(o){if(!this.double)return!this.nodes.handle.locked&&this.nodes.handle;var p=this.rects,q=Math.abs(o[this.mouseAxis[this.axis]]-p.handle[0][this.trackPos[this.axis]]);return p=Math.abs(o[this.mouseAxis[this.axis]]-p.handle[1][this.trackPos[this.axis]]),(o=o.target.closest("."+this.config.classes.handle))||(o=q>p?this.nodes.handle[1]:this.nodes.handle[0]),!o.locked&&o},n.prototype.onInit=function(){j(this.config.onInit)&&this.config.onInit.call(this,this.getValue())},n.prototype.onStart=function(){j(this.config.onStart)&&this.config.onStart.call(this,this.getValue())},n.prototype.onChange=function(){j(this.config.onChange)&&this.config.onChange.call(this,this.getValue())},n.prototype.onEnd=function(){j(this.config.onEnd)&&this.config.onEnd.call(this,this.getValue())},n.prototype.enable=function(){this.disabled&&(this.touch?this.nodes.container.addEventListener("touchstart",this.events.touchstart):this.nodes.container.addEventListener("mousedown",this.events.down),this.nodes.container.classList.remove(this.config.classes.disabled),this.disabled=!1)},n.prototype.disable=function(){this.disabled||(this.touch?this.nodes.container.removeEventListener("touchstart",this.events.touchstart):this.nodes.container.removeEventListener("mousedown",this.events.down),this.nodes.container.classList.add(this.config.classes.disabled),this.disabled=!0)},n.prototype.bind=function(){this.events={start:this.start.bind(this),move:this.move.bind(this),stop:this.stop.bind(this),update:this.update.bind(this),reset:this.reset.bind(this),set:this.native.bind(this),key:this.keydown.bind(this)},this.events.scroll=m(this.events.update,this.config.updateThrottle),this.events.resize=m(this.events.update,this.config.updateThrottle),document.addEventListener("scroll",this.events.scroll,!1),window.addEventListener("resize",this.events.resize,!1),this.double&&document.addEventListener("keydown",this.events.key,!1),this.nodes.container.addEventListener(this.touch?"touchstart":"mousedown",this.events.start,!1),this.input.addEventListener("input",this.events.set,!1),this.input.form&&this.input.form.addEventListener("reset",this.events.reset,!1)},n.prototype.unbind=function(){document.removeEventListener("scroll",this.events.scroll),window.removeEventListener("resize",this.events.resize),this.double&&document.removeEventListener("keydown",this.events.key),this.nodes.container.removeEventListener(this.touch?"touchstart":"mousedown",void 0),this.input.removeEventListener("input",this.events.set),this.input.form&&this.input.form.removeEventListener("reset",this.events.reset),this.events=null},n.prototype.destroy=function(){this.input.rangeable&&(this.unbind(),this.input.classList.remove(this.config.classes.input),this.nodes.container.parentNode.replaceChild(this.input,this.nodes.container),delete this.input.rangeable,this.initialised=!1)},n}); |
{ | ||
"name": "rangeable", | ||
"version": "0.0.11", | ||
"version": "0.1.0", | ||
"description": "A dependency-free, responsive and touch-enabled javascript range slider.", | ||
@@ -5,0 +5,0 @@ "main": "dist/rangeable.min.js", |
510
src/index.js
/*! | ||
* | ||
* Rangeable | ||
* Copyright (c) 2018 Karl Saunders | ||
* Copyright (c) 2018 Karl Saunders (mobius1(at)gmx(dot)com) | ||
* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) | ||
* and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. | ||
* | ||
* Version: 0.0.11 | ||
* Version: 0.1.0 | ||
* | ||
*/ | ||
class Rangeable { | ||
constructor(input, config) { | ||
(function(root, factory) { | ||
var plugin = "Rangeable"; | ||
if (typeof exports === "object") { | ||
module.exports = factory(plugin); | ||
} else if (typeof define === "function" && define.amd) { | ||
define([], factory); | ||
} else { | ||
root[plugin] = factory(plugin); | ||
} | ||
})(typeof global !== 'undefined' ? global : this.window || this.global, function() { | ||
"use strict"; | ||
const version = "0.1.0"; | ||
/* HELPERS*/ | ||
/** | ||
* addEventListener shortcut | ||
* @param {HTMLElement} el | ||
* @param {String} type | ||
* @param {Function} callback | ||
* @return {Void} | ||
*/ | ||
const on = (el,type,callback) => { | ||
el.addEventListener(type, callback, false); | ||
}; | ||
/** | ||
* removeEventListener shortcut | ||
* @param {HTMLElement} el | ||
* @param {String} type | ||
* @param {Function} callback | ||
* @return {Void} | ||
*/ | ||
const off = (el,type,callback) => { | ||
el.removeEventListener(type, callback); | ||
}; | ||
/** | ||
* createElement helper | ||
* @param {String} type | ||
* @param {String} obj | ||
* @return {HTMLElement} | ||
*/ | ||
const createElement = function(type, obj) { | ||
const el = document.createElement(type); | ||
if (obj) { | ||
el.classList.add(obj); | ||
} | ||
return el; | ||
}; | ||
/** | ||
* Check prop is defined and it is a function | ||
* @param {Mixed} func | ||
* @return {Boolean} | ||
*/ | ||
const isFunction = function(func) { | ||
return func && typeof func === "function"; | ||
}; | ||
/** | ||
* Throttle for resize / scroll | ||
* @param {Function} fn | ||
* @param {Number} limit | ||
* @param {Object} context | ||
* @return {Function} | ||
*/ | ||
const throttle = function(fn, limit, context) { | ||
let wait; | ||
return function() { | ||
context = context || this; | ||
if (!wait) { | ||
fn.apply(context, arguments); | ||
wait = true; | ||
return setTimeout(function() { | ||
wait = false; | ||
}, limit); | ||
} | ||
}; | ||
}; | ||
/** | ||
* Rangeable | ||
* @param {String|HTMLElement} input | ||
* @param {Object} config | ||
*/ | ||
const Rangeable = function(input, config) { | ||
this.plugins = ["ruler"]; | ||
const defaultConfig = { | ||
type: "single", | ||
tooltips: "always", | ||
updateThrottle: 30, | ||
classes: { | ||
@@ -50,3 +139,3 @@ input: "rangeable-input", | ||
this.onInit(); | ||
} | ||
}; | ||
@@ -57,3 +146,3 @@ /** | ||
*/ | ||
init() { | ||
Rangeable.prototype.init = function() { | ||
if (!this.input.rangeable) { | ||
@@ -99,24 +188,22 @@ const props = { min: 0, max: 100, step: 1, value: this.input.value }; | ||
*/ | ||
render() { | ||
Rangeable.prototype.render = function() { | ||
const o = this.config; | ||
const c = o.classes; | ||
const container = this.createElement("div", c.container); | ||
const track = this.createElement("div", c.track); | ||
const progress = this.createElement("div", c.progress); | ||
const container = createElement("div", c.container); | ||
const track = createElement("div", c.track); | ||
const progress = createElement("div", c.progress); | ||
let handle = this.createElement("div", c.handle); | ||
let tooltip = this.createElement("div", c.tooltip); | ||
let handle = createElement("div", c.handle); | ||
let tooltip = createElement("div", c.tooltip); | ||
track.appendChild(progress); | ||
if (this.double) { | ||
handle = [ | ||
this.createElement("div", c.handle), | ||
this.createElement("div", c.handle) | ||
createElement("div", c.handle), | ||
createElement("div", c.handle) | ||
]; | ||
tooltip = [ | ||
this.createElement("div", c.tooltip), | ||
this.createElement("div", c.tooltip), | ||
this.createElement("div", c.tooltip) | ||
createElement("div", c.tooltip), | ||
createElement("div", c.tooltip), | ||
createElement("div", c.tooltip) | ||
]; | ||
@@ -129,2 +216,9 @@ | ||
node.tabIndex = 1; | ||
// locked handles? | ||
if ( o.handles && o.handles[i] ) { | ||
if ( o.handles[i].locked && o.handles[i].locked === true ) { | ||
node.locked = true; | ||
} | ||
} | ||
}); | ||
@@ -144,6 +238,11 @@ | ||
handle.appendChild(tooltip); | ||
// locked handle? | ||
if ( o.handle ) { | ||
if ( o.handle.locked && o.handle.locked === true ) { | ||
handle.locked = true; | ||
} | ||
} | ||
} | ||
this.nodes = { container, track, progress, handle, tooltip }; | ||
container.appendChild(track); | ||
@@ -169,2 +268,40 @@ | ||
this.nodes = { container, track, progress, handle, tooltip }; | ||
if ( this.double ) { | ||
if ( o.handles ) { | ||
this.nodes.buffers = []; | ||
this.limits = []; | ||
const buffers = createElement("div", "rangeable-buffers"); | ||
o.handles.forEach((obj, i) => { | ||
if ( obj.min !== undefined && obj.max !== undefined ) { | ||
const buffer = createElement("div", "rangeable-buffer"); | ||
buffers.appendChild(buffer); | ||
this.nodes.buffers.push(buffer); | ||
this.limits[i] = { min: obj.min, max: obj.max }; | ||
} | ||
}); | ||
track.appendChild(buffers); | ||
} | ||
} else { | ||
if ( o.handle ) { | ||
if ( o.handle.min !== undefined && o.handle.max !== undefined ) { | ||
const buffer = createElement("div", "rangeable-buffer"); | ||
track.appendChild(buffer); | ||
this.nodes.buffer = buffer; | ||
this.limits = { min: o.handle.min, max: o.handle.max }; | ||
} | ||
} | ||
} | ||
track.appendChild(progress); | ||
this.input.parentNode.insertBefore(container, this.input); | ||
@@ -180,3 +317,7 @@ container.insertBefore(this.input, track); | ||
reset() { | ||
/** | ||
* Reset the value(s) to default | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.reset = function() { | ||
if (this.double) { | ||
@@ -190,3 +331,7 @@ this.input.defaultValues.forEach(this.setValue, this); | ||
setValueFromPosition(e) { | ||
/** | ||
* Set the value from the position of pointer over the track | ||
* @param {Object} e | ||
*/ | ||
Rangeable.prototype.setValueFromPosition = function(e) { | ||
const min = parseFloat(this.input.min); | ||
@@ -237,9 +382,6 @@ const max = parseFloat(this.input.max); | ||
index = this.activeHandle.index; | ||
if (!index && val >= this.input.values[1]) { | ||
val = this.input.values[1]; | ||
} else if (index && val <= this.input.values[0]) { | ||
val = this.input.values[0]; | ||
} | ||
} | ||
val = this.limit(val, index); | ||
this.setValue(val, index); | ||
@@ -249,7 +391,7 @@ } | ||
/** | ||
* Mousesown / touchstart method | ||
* Mousedown / touchstart callback | ||
* @param {Object} e | ||
* @return {Void} | ||
*/ | ||
start(e) { | ||
Rangeable.prototype.start = function(e) { | ||
e.preventDefault(); | ||
@@ -267,2 +409,6 @@ | ||
if ( !this.activeHandle ) { | ||
return false; | ||
} | ||
this.activeHandle.classList.add("active"); | ||
@@ -273,8 +419,8 @@ | ||
if (this.touch) { | ||
document.addEventListener("touchmove", this.events.move, false); | ||
document.addEventListener("touchend", this.events.stop, false); | ||
document.addEventListener("touchcancel", this.events.stop, false); | ||
on(document, "touchmove", this.events.move); | ||
on(document, "touchend", this.events.stop); | ||
on(document, "touchcancel", this.events.stop); | ||
} else { | ||
document.addEventListener("mousemove", this.events.move, false); | ||
document.addEventListener("mouseup", this.events.stop, false); | ||
on(document, "mousemove", this.events.move); | ||
on(document, "mouseup", this.events.stop); | ||
} | ||
@@ -284,7 +430,7 @@ } | ||
/** | ||
* Mousemove / touchmove method | ||
* Mousemove / touchmove callback | ||
* @param {Object} e | ||
* @return {Void} | ||
*/ | ||
move(e) { | ||
Rangeable.prototype.move = function(e) { | ||
this.setValueFromPosition(e); | ||
@@ -297,7 +443,7 @@ this.lastPos = this.touch | ||
/** | ||
* Mouseup / touchend method | ||
* Mouseup / touchend callback | ||
* @param {Object} e | ||
* @return {Void} | ||
*/ | ||
stop(e) { | ||
Rangeable.prototype.stop = function(e) { | ||
this.stopValue = this.getValue(); | ||
@@ -312,9 +458,11 @@ | ||
document.removeEventListener("mousemove", this.events.move); | ||
document.removeEventListener("mouseup", this.events.stop); | ||
if (this.touch) { | ||
off(document, "touchmove", this.events.move); | ||
off(document, "touchend", this.events.stop); | ||
off(document, "touchcancel", this.events.stop); | ||
} else { | ||
off(document, "mousemove", this.events.move); | ||
off(document, "mouseup", this.events.stop); | ||
} | ||
document.removeEventListener("touchmove", this.events.move); | ||
document.removeEventListener("touchend", this.events.stop); | ||
document.removeEventListener("touchcancel", this.events.stop); | ||
if (this.startValue !== this.stopValue) { | ||
@@ -327,3 +475,8 @@ this.input.dispatchEvent(new Event("change")); | ||
keydown(e) { | ||
/** | ||
* Keydown callback | ||
* @param {Object} e | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.keydown = function(e) { | ||
if ( this.double ) { | ||
@@ -347,3 +500,8 @@ this.nodes.handle.forEach(node => { | ||
stepUp(index) { | ||
/** | ||
* Increase the value by step | ||
* @param {Number} index | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.stepUp = function(index) { | ||
const step = parseFloat(this.input.step); | ||
@@ -362,3 +520,8 @@ | ||
stepDown(index) { | ||
/** | ||
* Decrease the value by step | ||
* @param {Number} index | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.stepDown = function(index) { | ||
const step = parseFloat(this.input.step); | ||
@@ -377,3 +540,9 @@ | ||
limit(value, index) { | ||
/** | ||
* Check the value is within the limits | ||
* @param {Number} value | ||
* @param {Number} index | ||
* @return {Number} | ||
*/ | ||
Rangeable.prototype.limit = function(value, index) { | ||
const el = this.input; | ||
@@ -390,2 +559,26 @@ let min = parseFloat(el.min); | ||
} | ||
if ( this.limits ) { | ||
if (!index) { | ||
if ( value > this.limits[0].max ) { | ||
value = this.limits[0].max; | ||
} else if ( value < this.limits[0].min ) { | ||
value = this.limits[0].min; | ||
} | ||
} else { | ||
if ( value > this.limits[1].max ) { | ||
value = this.limits[1].max; | ||
} else if ( value < this.limits[1].min ) { | ||
value = this.limits[1].min; | ||
} | ||
} | ||
} | ||
} else { | ||
if ( this.limits ) { | ||
if ( value > this.limits.max ) { | ||
value = this.limits.max; | ||
} else if ( value < this.limits.min ) { | ||
value = this.limits.min; | ||
} | ||
} | ||
} | ||
@@ -403,6 +596,6 @@ | ||
/** | ||
* Recache the dimensions | ||
* Recache dimensions | ||
* @return {Void} | ||
*/ | ||
recalculate() { | ||
Rangeable.prototype.recalculate = function() { | ||
let handle = []; | ||
@@ -428,3 +621,3 @@ | ||
*/ | ||
update() { | ||
Rangeable.prototype.update = function() { | ||
this.recalculate(); | ||
@@ -439,16 +632,45 @@ | ||
const size = this.rects.container[this.trackSize[this.axis]]; | ||
if ( this.double ) { | ||
if ( this.config.handles && this.nodes.buffers ) { | ||
this.config.handles.forEach((obj, i) => { | ||
const buffer = this.nodes.buffers[i]; | ||
const offset = obj.min / this.input.max * size; | ||
buffer.style[this.config.vertical ? "bottom" : "left"] = `${offset}px`; | ||
buffer.style[this.trackSize[this.axis]] = `${(obj.max / this.input.max * size) - offset}px`; | ||
}); | ||
} | ||
} else { | ||
if ( this.config.handle ) { | ||
const buffer = this.nodes.buffer; | ||
const offset = this.config.handle.min / this.input.max * size; | ||
buffer.style.left = `${offset}px`; | ||
buffer.style.width = `${(this.config.handle.max / this.input.max * size) - offset}px`; | ||
} | ||
} | ||
const value = this.getValue(); | ||
if (this.double) { | ||
this.input.values.forEach((val, i) => { | ||
this.setValue(val, i); | ||
this.setValue(this.limit(val, i), i); | ||
}); | ||
} else { | ||
this.setValue(); | ||
this.setValue(this.limit(value)); | ||
} | ||
} | ||
getValue() { | ||
/** | ||
* Get the current value(s) | ||
* @return {Number|Array} | ||
*/ | ||
Rangeable.prototype.getValue = function() { | ||
return this.double ? this.input.values : this.input.value; | ||
} | ||
parseValue(value) { | ||
/** | ||
* Parse the value correctly | ||
* @param {Mixed} value | ||
* @return {Number} | ||
*/ | ||
Rangeable.prototype.parseValue = function(value) { | ||
const min = parseFloat(this.input.min); | ||
@@ -470,2 +692,3 @@ const max = parseFloat(this.input.max); | ||
} | ||
return value; | ||
@@ -475,7 +698,7 @@ } | ||
/** | ||
* Set the input value | ||
* Set the current value(s) | ||
* @param {Number} value | ||
* @param {Number} index | ||
*/ | ||
setValue(value, index) { | ||
Rangeable.prototype.setValue = function(value, index) { | ||
const rects = this.rects; | ||
@@ -542,3 +765,7 @@ const nodes = this.nodes; | ||
native() { | ||
/** | ||
* Native callback | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.native = function() { | ||
this.nativeEvent = true; | ||
@@ -550,6 +777,6 @@ | ||
/** | ||
* Set the bar size / position based on the value | ||
* @param {Number} value | ||
* Set the postion / size of the progress bar. | ||
* @param {[type]} value [description] | ||
*/ | ||
setPosition(value) { | ||
Rangeable.prototype.setPosition = function(value) { | ||
let width; | ||
@@ -576,7 +803,10 @@ | ||
/** | ||
* Get the position of handle from the value | ||
* @param {Number} value The val to calculate the handle position | ||
* Get the position along the track from a value. | ||
* @param {Number} value | ||
* @return {Number} | ||
*/ | ||
getPosition(value = this.input.value) { | ||
Rangeable.prototype.getPosition = function(value) { | ||
if ( value === undefined ) { | ||
value = this.input.value; | ||
} | ||
const min = parseFloat(this.input.min); | ||
@@ -592,8 +822,8 @@ const max = parseFloat(this.input.max); | ||
* Get the correct handle on mousedown / touchstart | ||
* @param {Object} e Event | ||
* @return {Obejct} HTMLElement | ||
* @param {Object} e | ||
* @return {Boolean|HTMLElement} | ||
*/ | ||
getHandle(e) { | ||
Rangeable.prototype.getHandle = function(e) { | ||
if (!this.double) { | ||
return this.nodes.handle; | ||
return this.nodes.handle.locked ? false : this.nodes.handle; | ||
} | ||
@@ -608,17 +838,21 @@ | ||
); | ||
const handle = e.target.closest(`.${this.config.classes.handle}`); | ||
let handle = e.target.closest(`.${this.config.classes.handle}`); | ||
if (handle) { | ||
return handle; | ||
} else { | ||
if (!handle) { | ||
if (distA > distB) { | ||
return this.nodes.handle[1]; | ||
handle = this.nodes.handle[1]; | ||
} else { | ||
return this.nodes.handle[0]; | ||
handle = this.nodes.handle[0]; | ||
} | ||
} | ||
return handle.locked ? false : handle; | ||
} | ||
onInit() { | ||
if (this.isFunction(this.config.onInit)) { | ||
/** | ||
* onInit callback | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.onInit = function() { | ||
if (isFunction(this.config.onInit)) { | ||
this.config.onInit.call(this, this.getValue()); | ||
@@ -628,4 +862,8 @@ } | ||
onStart() { | ||
if (this.isFunction(this.config.onStart)) { | ||
/** | ||
* onStart callback | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.onStart = function() { | ||
if (isFunction(this.config.onStart)) { | ||
this.config.onStart.call(this, this.getValue()); | ||
@@ -635,4 +873,8 @@ } | ||
onChange() { | ||
if (this.isFunction(this.config.onChange)) { | ||
/** | ||
* onChange callback | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.onChange = function() { | ||
if (isFunction(this.config.onChange)) { | ||
this.config.onChange.call(this, this.getValue()); | ||
@@ -642,4 +884,8 @@ } | ||
onEnd() { | ||
if (this.isFunction(this.config.onEnd)) { | ||
/** | ||
* onEnd callback | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.onEnd = function() { | ||
if (isFunction(this.config.onEnd)) { | ||
this.config.onEnd.call(this, this.getValue()); | ||
@@ -649,3 +895,7 @@ } | ||
enable() { | ||
/** | ||
* Enable the instance | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.enable = function() { | ||
if (this.disabled) { | ||
@@ -655,4 +905,3 @@ if (this.touch) { | ||
"touchstart", | ||
this.events.touchstart, | ||
false | ||
this.events.touchstart | ||
); | ||
@@ -669,3 +918,7 @@ } else { | ||
disable() { | ||
/** | ||
* Disable the instance | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.disable = function() { | ||
if (!this.disabled) { | ||
@@ -687,3 +940,7 @@ if (this.touch) { | ||
bind() { | ||
/** | ||
* Add event listeners | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.bind = function() { | ||
this.events = { | ||
@@ -699,53 +956,53 @@ start: this.start.bind(this), | ||
this.events.scroll = this.throttle(this.events.update, 100); | ||
this.events.resize = this.throttle(this.events.update, 50); | ||
this.events.scroll = throttle(this.events.update, this.config.updateThrottle); | ||
this.events.resize = throttle(this.events.update, this.config.updateThrottle); | ||
// throttle the scroll callback for performance | ||
document.addEventListener("scroll", this.events.scroll, false); | ||
on(document, "scroll", this.events.scroll); | ||
// throttle the resize callback for performance | ||
window.addEventListener("resize", this.events.resize, false); | ||
on(window, "resize", this.events.resize); | ||
if ( this.double ) { | ||
document.addEventListener("keydown", this.events.key, false); | ||
on(document, "keydown", this.events.key); | ||
} | ||
// touchstart/mousedown | ||
this.nodes.container.addEventListener( | ||
on(this.nodes.container, | ||
this.touch ? "touchstart" : "mousedown", | ||
this.events.start, | ||
false | ||
this.events.start | ||
); | ||
// listen for native input to allow keyboard control on focus | ||
this.input.addEventListener("input", this.events.set); | ||
on(this.input, "input", this.events.set); | ||
// detect form reset | ||
if (this.input.form) { | ||
this.input.form.addEventListener("reset", this.events.reset, false); | ||
on(this.input.form, "reset", this.events.reset); | ||
} | ||
} | ||
unbind() { | ||
/** | ||
* Remove event listeners | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.unbind = function() { | ||
// throttle the scroll callback for performance | ||
document.removeEventListener("scroll", this.events.scroll); | ||
off(document, "scroll", this.events.scroll); | ||
// throttle the resize callback for performance | ||
window.removeEventListener("resize", this.events.resize); | ||
off(window, "resize", this.events.resize); | ||
if ( this.double ) { | ||
document.removeEventListener("keydown", this.events.key); | ||
off(document, "keydown", this.events.key); | ||
} | ||
this.nodes.container.removeEventListener( | ||
this.touch ? "touchstart" : "mousedown", | ||
this.events.start | ||
); | ||
off(this.nodes.container, this.touch ? "touchstart" : "mousedown"); | ||
// listen for native input to allow keyboard control on focus | ||
this.input.removeEventListener("input", this.events.set); | ||
off(this.input, "input", this.events.set); | ||
// detect form reset | ||
if (this.input.form) { | ||
this.input.form.removeEventListener("reset", this.events.reset); | ||
off(this.input.form, "reset", this.events.reset); | ||
} | ||
@@ -760,3 +1017,3 @@ | ||
*/ | ||
destroy() { | ||
Rangeable.prototype.destroy = function() { | ||
if (this.input.rangeable) { | ||
@@ -782,34 +1039,3 @@ // remove all event events | ||
/** | ||
* Create DOM element helper | ||
* @param {String} a nodeName | ||
* @param {String|Object} b className or properties / attributes | ||
* @return {Object} | ||
*/ | ||
createElement(type, obj) { | ||
const el = document.createElement(type); | ||
if (obj) { | ||
el.classList.add(obj); | ||
} | ||
return el; | ||
} | ||
isFunction(f) { | ||
return f && typeof f === "function"; | ||
} | ||
// throttler | ||
throttle(fn, limit, context) { | ||
let wait; | ||
return function() { | ||
context = context || this; | ||
if (!wait) { | ||
fn.apply(context, arguments); | ||
wait = true; | ||
return setTimeout(function() { | ||
wait = false; | ||
}, limit); | ||
} | ||
}; | ||
} | ||
} | ||
return Rangeable; | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
272395
845