rangeable
Advanced tools
Comparing version 0.1.5 to 0.1.6
@@ -8,5 +8,5 @@ /*! | ||
* | ||
* Version: 0.1.5 | ||
* Version: 0.1.6 | ||
* | ||
*/ | ||
(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(p,q){var r=document.createElement(p);return q&&r.classList.add(q),r},j=function(p){return p&&"function"==typeof p},n=function(p,q,r){var s;return function(){if(r=r||this,!s)return p.apply(r,arguments),s=!0,setTimeout(function(){s=!1},q)}},o=function(p,q){this.plugins=["ruler"],"string"==typeof p&&(p=document.querySelector(p)),this.input=p,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",track:"rangeable-track",multiple:"rangeable-multiple",disabled:"rangeable-disabled",tooltips:"rangeable-tooltips",tooltip:"rangeable-tooltip",visible:"rangeable-tooltips--visible"}},q),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.version="0.1.5",this.init(),this.onInit()};return o.prototype.init=function(){if(!this.input.rangeable){var q,p={min:0,max:100,step:1,value:this.input.value};for(q in p)this.input[q]||(this.input[q]=p[q]),void 0!==this.config[q]&&(this.input[q]=this.config[q]);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}},o.prototype.render=function(){var p=this,q=this.config,r=q.classes,s=i("div",r.container),t=i("div",r.track),u=i("div",r.progress),v=i("div",r.handle),w=i("div",r.tooltip);if(this.input.tabIndex=-1,this.double?(v=[i("div",r.handle),i("div",r.handle)],w=[i("div",r.tooltip),i("div",r.tooltip),i("div",r.tooltip)],v.forEach(function(y,z){y.index=z,u.appendChild(y),y.appendChild(w[z]),y.tabIndex=1,q.handles&&q.handles[z]&&q.handles[z].locked&&!0===q.handles[z].locked&&(y.locked=!0)}),q.vertical&&u.appendChild(v[0]),u.appendChild(w[2]),s.classList.add(r.multiple)):(u.appendChild(v),v.appendChild(w),v.tabIndex=1,q.handle&&q.handle.locked&&!0===q.handle.locked&&(v.locked=!0)),s.appendChild(t),q.vertical&&s.classList.add(r.vertical),q.size&&(s.style[this.trackSize[this.axis]]=isNaN(q.size)?q.size:q.size+"px"),q.tooltips&&(s.classList.add(r.tooltips),"string"==typeof q.tooltips&&"always"===q.tooltips&&s.classList.add(r.visible)),this.nodes={container:s,track:t,progress:u,handle:v,tooltip:w},this.double){this.nodes.buffer=[];var x=i("div","rangeable-buffers");this.input.values.forEach(function(y,z){var A=i("div","rangeable-buffer");x.appendChild(A),p.nodes.buffer.push(A),t.appendChild(x),q.handles&&(p.limits=[{},{}],void 0!==q.handles[z].min&&(p.limits[z].min=q.handles[z].min),void 0!==q.handles[z].max&&(p.limits[z].max=q.handles[z].max))}),this.setLimits(q.handles)}else v=i("div","rangeable-buffer"),t.appendChild(v),this.nodes.buffer=v,t.appendChild(v),q.handle&&(this.limits={},void 0!==q.handle.min&&(this.limits.min=q.handle.min),void 0!==q.handle.max&&(this.limits.max=q.handle.max)),this.setLimits(q.handle);t.appendChild(u),this.input.parentNode.insertBefore(s,this.input),s.insertBefore(this.input,t),this.input.classList.add(r.input),this.bind(),this.update()},o.prototype.reset=function(){this.double?this.input.defaultValues.forEach(this.setValue,this):this.setValue(this.input.defaultValue),this.onEnd()},o.prototype.setValueFromPosition=function(p){var q=this.getLimits(),r=parseFloat(this.input.step),s=this.touch?p.touches[0][this.mouseAxis[this.axis]]:p[this.mouseAxis[this.axis]],t=s-this.rects.container[this.trackPos[this.axis]],u=this.rects.container[this.trackSize[this.axis]];return"mousedown"===p.type&&(!this.double&&this.nodes.handle.contains(p.target)||this.double&&(this.nodes.handle[0].contains(p.target)||this.nodes.handle[1].contains(p.target)))?!1:(p=(this.config.vertical?100*((u-t)/u):100*(t/u))*(q.max-q.min)/100+q.min,p=Math.ceil(p/r)*r,s>=this.lastPos&&(p-=r),parseFloat(p)!==parseFloat(this.startValue)&&void(r=!1,this.double&&(r=this.activeHandle.index),p=this.limit(p,r),this.setValue(p,r)))},o.prototype.start=function(p){return p.preventDefault(),this.startValue=this.getValue(),this.onStart(),this.nodes.container.classList.add("dragging"),this.recalculate(),this.activeHandle=this.getHandle(p),!!this.activeHandle&&void(this.activeHandle.classList.add("active"),this.setValueFromPosition(p),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)))},o.prototype.move=function(p){this.setValueFromPosition(p),this.lastPos=this.touch?p.touches[0][this.mouseAxis[this.axis]]:p[this.mouseAxis[this.axis]]},o.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},o.prototype.keydown=function(p){var q=this,r=function(s){switch(p.key){case"ArrowRight":case"ArrowUp":q.stepUp(s);break;case"ArrowLeft":case"ArrowDown":q.stepDown(s);}};this.double?this.nodes.handle.forEach(function(s){s===document.activeElement&&r(s.index)}):this.nodes.handle===document.activeElement&&r()},o.prototype.stepUp=function(p){var q=parseFloat(this.input.step),r=this.getValue();this.double&&void 0!==p&&(r=r[p]),q=this.limit(parseFloat(r)+q,p),this.setValue(q,p)},o.prototype.stepDown=function(p){var q=parseFloat(this.input.step),r=this.getValue();this.double&&void 0!==p&&(r=r[p]),q=this.limit(parseFloat(r)-q,p),this.setValue(q,p)},o.prototype.limit=function(p,q){var r=this.input,s=this.getLimits();return p=parseFloat(p),this.double&&void 0!==q?(!q&&p>r.values[1]?p=r.values[1]:0<q&&p<r.values[0]&&(p=r.values[0]),this.limits)&&(q?p>this.limits[1].max?p=this.limits[1].max:p<this.limits[1].min&&(p=this.limits[1].min):p>this.limits[0].max?p=this.limits[0].max:p<this.limits[0].min&&(p=this.limits[0].min)):this.limits&&(p>this.limits.max?p=this.limits.max:p<this.limits.min&&(p=this.limits.min)),p>s.max?p=s.max:p<s.min&&(p=s.min),p=parseFloat(p),p=p.toFixed(this.accuracy)},o.prototype.recalculate=function(){var p=[];this.double?this.nodes.handle.forEach(function(q,r){p[r]=q.getBoundingClientRect()}):p=this.nodes.handle.getBoundingClientRect(),this.rects={handle:p,container:this.nodes.container.getBoundingClientRect()}},o.prototype.update=function(){var p=this;this.recalculate(),this.accuracy=0,this.input.step.includes(".")&&(this.accuracy=(this.input.step.split(".")[1]||[]).length);var q=this.getValue(),r=this.getLimits(),s=this.rects.container[this.trackSize[this.axis]],t=function(u,v,w){u.style[p.config.vertical?"bottom":"left"]=v+"px",u.style[p.trackSize[p.axis]]=w/r.max*s-v+"px"};this.double?(this.limits&&this.limits.forEach(function(u,v){t(p.nodes.buffer[v],u.min/r.max*s,u.max)}),this.input.values.forEach(function(u,v){p.setValue(p.limit(u,v),v)})):(this.limits&&t(this.nodes.buffer,this.limits.min/r.max*s,this.limits.max),this.setValue(this.limit(q)))},o.prototype.getValue=function(){return this.double?this.input.values:this.input.value},o.prototype.setValue=function(p,q){var r=this.nodes;if(this.double&&void 0===q)return!1;void 0===p&&(p=this.input.value),p=this.limit(p,q);var s=this.initialised&&(p!==this.input.value||this.nativeEvent);if(this.double){var t=this.input.values;if(t[q]=p,this.config.tooltips){r.tooltip[q].textContent=p;var u=r.tooltip[0].getBoundingClientRect(),v=r.tooltip[1].getBoundingClientRect();u=!(u.right<v.left||u.left>v.right||u.bottom<v.top||u.top>v.bottom),r.container.classList.toggle("combined-tooltip",u),u&&(r.tooltip[2].textContent=t[0]===t[1]?t[0]:t[0]+" - "+t[1])}}else this.input.value=p,r.tooltip.textContent=p;this.setPosition(p,q),s&&(this.onChange(),this.nativeEvent||this.input.dispatchEvent(new Event("input")),this.nativeEvent=!1)},o.prototype.native=function(){this.nativeEvent=!0,this.setValue()},o.prototype.getLimits=function(){return{min:parseFloat(this.input.min),max:parseFloat(this.input.max)}},o.prototype.setLimits=function(p){var q=this;if(void 0===p)return!1;this.limits||(this.limits=p);var r=function(s,t){void 0!==t.min&&(s.min=t.min),void 0!==t.max&&(s.max=t.max)};this.double?p.forEach(function(s,t){r(q.limits[t],s)}):r(this.limits,p),this.update()},o.prototype.setPosition=function(p){if(this.double){p=this.getPosition(this.input.values[0]);var q=this.getPosition(this.input.values[1]);this.nodes.progress.style[this.config.vertical?"bottom":"left"]=p+"px",p=q-p}else p=this.getPosition();this.nodes.progress.style[this.trackSize[this.axis]]=p+"px"},o.prototype.getPosition=function(p){void 0===p&&(p=this.input.value);var q=this.getLimits();return(p-q.min)/(q.max-q.min)*this.rects.container[this.trackSize[this.axis]]},o.prototype.getHandle=function(p){if(!this.double)return!this.nodes.handle.locked&&this.nodes.handle;var q=this.rects,r=Math.abs(p[this.mouseAxis[this.axis]]-q.handle[0][this.trackPos[this.axis]]);return q=Math.abs(p[this.mouseAxis[this.axis]]-q.handle[1][this.trackPos[this.axis]]),(p=p.target.closest("."+this.config.classes.handle))||(p=r>q?this.nodes.handle[1]:this.nodes.handle[0]),!p.locked&&p},o.prototype.enable=function(){this.input.disabled&&(this.nodes.container.addEventListener(this.touch?"touchstart":"mousedown",this.events.start,!1),this.double?this.nodes.handle.forEach(function(p){return p.tabIndex=1}):this.nodes.handle.tabIndex=1,this.nodes.container.classList.remove(this.config.classes.disabled),this.input.disabled=!1)},o.prototype.disable=function(){this.input.disabled||(this.nodes.container.removeEventListener(this.touch?"touchstart":"mousedown",this.events.start),this.double?this.nodes.handle.forEach(function(p){return p.removeAttribute("tabindex")}):this.nodes.handle.removeAttribute("tabindex"),this.nodes.container.classList.add(this.config.classes.disabled),this.input.disabled=!0)},o.prototype.bind=function(){var p=this;this.events={},"start move stop update reset native keydown".split(" ").forEach(function(q){p.events[q]=p[q].bind(p)}),this.events.scroll=n(this.events.update,this.config.updateThrottle),this.events.resize=n(this.events.update,this.config.updateThrottle),document.addEventListener("scroll",this.events.scroll,!1),window.addEventListener("resize",this.events.resize,!1),document.addEventListener("keydown",this.events.keydown,!1),this.nodes.container.addEventListener(this.touch?"touchstart":"mousedown",this.events.start,!1),this.input.addEventListener("input",this.events.native,!1),this.input.form&&this.input.form.addEventListener("reset",this.events.reset,!1)},o.prototype.unbind=function(){document.removeEventListener("scroll",this.events.scroll),window.removeEventListener("resize",this.events.resize),document.removeEventListener("keydown",this.events.keydown),this.nodes.container.removeEventListener(this.touch?"touchstart":"mousedown",this.events.start),this.input.removeEventListener("input",this.events.native),this.input.form&&this.input.form.removeEventListener("reset",this.events.reset),this.events=null},o.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)},o.prototype.onInit=function(){j(this.config.onInit)&&this.config.onInit.call(this,this.getValue())},o.prototype.onStart=function(){j(this.config.onStart)&&this.config.onStart.call(this,this.getValue())},o.prototype.onChange=function(){j(this.config.onChange)&&this.config.onChange.call(this,this.getValue())},o.prototype.onEnd=function(){j(this.config.onEnd)&&this.config.onEnd.call(this,this.getValue())},o}); | ||
(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(s,t){var u=document.createElement(s);return t&&u.classList.add(t),u},j=function(s){return s&&"function"==typeof s},o=function(s,t,u){var v;return function(){if(u=u||this,!v)return s.apply(u,arguments),v=!0,setTimeout(function(){v=!1},t)}},q=function(s,t){this.plugins=["ruler"],"string"==typeof s&&(s=document.querySelector(s)),this.input=s,this.config=Object.assign({},{type:"single",tooltips:"always",updateThrottle:30,formatTooltip:function(u){return u},classes:{input:"rangeable-input",container:"rangeable-container",vertical:"rangeable-vertical",progress:"rangeable-progress",handle:"rangeable-handle",track:"rangeable-track",multiple:"rangeable-multiple",disabled:"rangeable-disabled",tooltips:"rangeable-tooltips",tooltip:"rangeable-tooltip",visible:"rangeable-tooltips--visible"}},t),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.version="0.1.6",this.init(),this.onInit()},r=q.prototype;return r.init=function(){if(!this.input.rangeable){var t,s={min:0,max:100,step:1,value:this.input.value};for(t in s)this.input[t]||(this.input[t]=s[t]),void 0!==this.config[t]&&(this.input[t]=this.config[t]);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}},r.render=function(){var s=this,t=this.config,u=t.classes,v=i("div",u.container),w=i("div",u.track),x=i("div",u.progress),y=i("div",u.handle),z=i("div",u.tooltip);if(this.input.tabIndex=-1,this.double){y=[i("div",u.handle),i("div",u.handle)],z=[];for(var A=0;3>A;A++)z[A]=i("div",u.tooltip);y.forEach(function(C,D){C.index=D,x.appendChild(C),C.appendChild(z[D]),C.tabIndex=1,t.controls&&t.controls[D]&&t.controls[D].locked&&!0===t.controls[D].locked&&(C.locked=!0)}),t.vertical&&x.appendChild(y[0]),x.appendChild(z[2]),v.classList.add(u.multiple)}else x.appendChild(y),y.appendChild(z),y.tabIndex=1,t.controls&&t.controls.locked&&!0===t.controls.locked&&(y.locked=!0);if(v.appendChild(w),t.vertical&&v.classList.add(u.vertical),t.size&&(v.style[this.trackSize[this.axis]]=isNaN(t.size)?t.size:t.size+"px"),t.tooltips&&(v.classList.add(u.tooltips),"string"==typeof t.tooltips&&"always"===t.tooltips&&v.classList.add(u.visible)),this.nodes={container:v,track:w,progress:x,handle:y,tooltip:z},this.double){this.nodes.buffer=[];var B=i("div","rangeable-buffers");this.input.values.forEach(function(C,D){var E=i("div","rangeable-buffer");B.appendChild(E),s.nodes.buffer.push(E),w.appendChild(B),t.controls&&(s.limits=[{},{}],void 0!==t.controls[D].min&&(s.limits[D].min=t.controls[D].min),void 0!==t.controls[D].max&&(s.limits[D].max=t.controls[D].max))})}else y=i("div","rangeable-buffer"),w.appendChild(y),this.nodes.buffer=y,w.appendChild(y),t.controls&&(this.limits={},void 0!==t.controls.min&&(this.limits.min=t.controls.min),void 0!==t.controls.max&&(this.limits.max=t.controls.max));this.setLimits(t.controls),w.appendChild(x),this.input.parentNode.insertBefore(v,this.input),v.insertBefore(this.input,w),this.input.classList.add(u.input),this.bind(),this.update()},r.reset=function(){this.double?this.input.defaultValues.forEach(this.setValue,this):this.setValue(this.input.defaultValue),this.onEnd()},r.setValueFromPosition=function(s){var t=this.getLimits(),u=parseFloat(this.input.step),v=this.touch?s.touches[0][this.mouseAxis[this.axis]]:s[this.mouseAxis[this.axis]],w=v-this.rects.container[this.trackPos[this.axis]],x=this.rects.container[this.trackSize[this.axis]];return"mousedown"===s.type&&(!this.double&&this.nodes.handle.contains(s.target)||this.double&&(this.nodes.handle[0].contains(s.target)||this.nodes.handle[1].contains(s.target)))?!1:(s=(this.config.vertical?100*((x-w)/x):100*(w/x))*(t.max-t.min)/100+t.min,s=Math.ceil(s/u)*u,v>=this.lastPos&&(s-=u),parseFloat(s)!==parseFloat(this.startValue)&&void(u=!1,this.double&&(u=this.activeHandle.index),s=this.limit(s,u),this.setValue(s,u)))},r.start=function(s){return s.preventDefault(),this.startValue=this.getValue(),this.onStart(),this.nodes.container.classList.add("dragging"),this.recalculate(),this.activeHandle=this.getHandle(s),!!this.activeHandle&&void(this.activeHandle.classList.add("active"),this.setValueFromPosition(s),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)))},r.move=function(s){this.setValueFromPosition(s),this.lastPos=this.touch?s.touches[0][this.mouseAxis[this.axis]]:s[this.mouseAxis[this.axis]]},r.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},r.keydown=function(s){var t=this,u=function(v){switch(s.key){case"ArrowRight":case"ArrowUp":t.stepUp(v);break;case"ArrowLeft":case"ArrowDown":t.stepDown(v);}};this.double?this.nodes.handle.forEach(function(v){v===document.activeElement&&u(v.index)}):this.nodes.handle===document.activeElement&&u()},r.stepUp=function(s){var t=parseFloat(this.input.step),u=this.getValue();this.double&&void 0!==s&&(u=u[s]),t=this.limit(parseFloat(u)+t,s),this.setValue(t,s)},r.stepDown=function(s){var t=parseFloat(this.input.step),u=this.getValue();this.double&&void 0!==s&&(u=u[s]),t=this.limit(parseFloat(u)-t,s),this.setValue(t,s)},r.limit=function(s,t){var u=this.input,v=this.getLimits();return s=parseFloat(s),this.double&&void 0!==t?(!t&&s>u.values[1]?s=u.values[1]:0<t&&s<u.values[0]&&(s=u.values[0]),this.limits)&&(t?s>this.limits[1].max?s=this.limits[1].max:s<this.limits[1].min&&(s=this.limits[1].min):s>this.limits[0].max?s=this.limits[0].max:s<this.limits[0].min&&(s=this.limits[0].min)):this.limits&&(s>this.limits.max?s=this.limits.max:s<this.limits.min&&(s=this.limits.min)),s>v.max?s=v.max:s<v.min&&(s=v.min),s=parseFloat(s),s=s.toFixed(this.accuracy)},r.recalculate=function(){var s=[];this.double?this.nodes.handle.forEach(function(t,u){s[u]=t.getBoundingClientRect()}):s=this.nodes.handle.getBoundingClientRect(),this.rects={handle:s,container:this.nodes.container.getBoundingClientRect()}},r.update=function(){var s=this;this.recalculate(),this.accuracy=0,this.input.step.includes(".")&&(this.accuracy=(this.input.step.split(".")[1]||[]).length);var t=this.getValue(),u=this.getLimits(),v=this.rects.container[this.trackSize[this.axis]],w=function(x,y,z){x.style[s.config.vertical?"bottom":"left"]=y+"px",x.style[s.trackSize[s.axis]]=z/u.max*v-y+"px"};this.double?(this.limits&&this.limits.forEach(function(x,y){w(s.nodes.buffer[y],x.min/u.max*v,x.max)}),this.input.values.forEach(function(x,y){s.setValue(s.limit(x,y),y)})):(this.limits&&w(this.nodes.buffer,this.limits.min/u.max*v,this.limits.max),this.setValue(this.limit(t)))},r.getValue=function(){return this.double?this.input.values:this.input.value},r.setValue=function(s,t){var u=this.nodes;if(this.double&&void 0===t)return!1;void 0===s&&(s=this.input.value),s=this.limit(s,t);var v=this.initialised&&(s!==this.input.value||this.nativeEvent),w=this.config.formatTooltip;if(this.double){var x=this.input.values;if(x[t]=s,this.config.tooltips){u.tooltip[t].textContent=w.call(this,s);var y=u.tooltip[0].getBoundingClientRect(),z=u.tooltip[1].getBoundingClientRect();y=!(y.right<z.left||y.left>z.right||y.bottom<z.top||y.top>z.bottom),u.container.classList.toggle("combined-tooltip",y),y&&(u.tooltip[2].textContent=x[0]===x[1]?w.call(this,x[0]):w.call(this,x[0])+" - "+w.call(this,x[1]))}}else this.input.value=s,u.tooltip.textContent=w.call(this,s);this.setPosition(s,t),v&&(this.onChange(),this.nativeEvent||this.input.dispatchEvent(new Event("input")),this.nativeEvent=!1)},r.native=function(){this.nativeEvent=!0,this.setValue()},r.getLimits=function(){return{min:parseFloat(this.input.min),max:parseFloat(this.input.max)}},r.setLimits=function(s){var t=this;if(void 0===s)return!1;this.limits||(this.limits=s);var u=function(v,w){void 0!==w.min&&(v.min=w.min),void 0!==w.max&&(v.max=w.max)};this.double?s.forEach(function(v,w){u(t.limits[w],v)}):u(this.limits,s),this.update()},r.setPosition=function(s){if(this.double){s=this.getPosition(this.input.values[0]);var t=this.getPosition(this.input.values[1]);this.nodes.progress.style[this.config.vertical?"bottom":"left"]=s+"px",s=t-s}else s=this.getPosition();this.nodes.progress.style[this.trackSize[this.axis]]=s+"px"},r.getPosition=function(s){void 0===s&&(s=this.input.value);var t=this.getLimits();return(s-t.min)/(t.max-t.min)*this.rects.container[this.trackSize[this.axis]]},r.getHandle=function(s){if(!this.double)return!this.nodes.handle.locked&&this.nodes.handle;var t=this.rects,u=Math.abs(s[this.mouseAxis[this.axis]]-t.handle[0][this.trackPos[this.axis]]);return t=Math.abs(s[this.mouseAxis[this.axis]]-t.handle[1][this.trackPos[this.axis]]),(s=s.target.closest("."+this.config.classes.handle))||(s=u>t?this.nodes.handle[1]:this.nodes.handle[0]),!s.locked&&s},r.enable=function(){this.input.disabled&&(this.nodes.container.addEventListener(this.touch?"touchstart":"mousedown",this.events.start,!1),this.double?this.nodes.handle.forEach(function(s){return s.tabIndex=1}):this.nodes.handle.tabIndex=1,this.nodes.container.classList.remove(this.config.classes.disabled),this.input.disabled=!1)},r.disable=function(){this.input.disabled||(this.nodes.container.removeEventListener(this.touch?"touchstart":"mousedown",this.events.start),this.double?this.nodes.handle.forEach(function(s){return s.removeAttribute("tabindex")}):this.nodes.handle.removeAttribute("tabindex"),this.nodes.container.classList.add(this.config.classes.disabled),this.input.disabled=!0)},r.bind=function(){var s=this;this.events={},"start move stop update reset native keydown".split(" ").forEach(function(t){s.events[t]=s[t].bind(s)}),this.events.scroll=o(this.events.update,this.config.updateThrottle),this.events.resize=o(this.events.update,this.config.updateThrottle),document.addEventListener("scroll",this.events.scroll,!1),window.addEventListener("resize",this.events.resize,!1),document.addEventListener("keydown",this.events.keydown,!1),this.nodes.container.addEventListener(this.touch?"touchstart":"mousedown",this.events.start,!1),this.input.addEventListener("input",this.events.native,!1),this.input.form&&this.input.form.addEventListener("reset",this.events.reset,!1)},r.unbind=function(){document.removeEventListener("scroll",this.events.scroll),window.removeEventListener("resize",this.events.resize),document.removeEventListener("keydown",this.events.keydown),this.nodes.container.removeEventListener(this.touch?"touchstart":"mousedown",this.events.start),this.input.removeEventListener("input",this.events.native),this.input.form&&this.input.form.removeEventListener("reset",this.events.reset),this.events=null},r.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)},r.onInit=function(){j(this.config.onInit)&&this.config.onInit.call(this,this.getValue())},r.onStart=function(){j(this.config.onStart)&&this.config.onStart.call(this,this.getValue())},r.onChange=function(){j(this.config.onChange)&&this.config.onChange.call(this,this.getValue())},r.onEnd=function(){j(this.config.onEnd)&&this.config.onEnd.call(this,this.getValue())},q}); |
{ | ||
"name": "rangeable", | ||
"version": "0.1.5", | ||
"version": "0.1.6", | ||
"description": "A dependency-free, responsive and touch-enabled javascript range slider written in vanilla javascript.", | ||
@@ -5,0 +5,0 @@ "main": "dist/rangeable.min.js", |
1731
src/index.js
@@ -8,3 +8,3 @@ /*! | ||
* | ||
* Version: 0.1.5 | ||
* Version: 0.1.6 | ||
* | ||
@@ -22,1073 +22,1070 @@ */ | ||
} | ||
})( | ||
typeof global !== "undefined" ? global : this.window || this.global, | ||
function() { | ||
"use strict"; | ||
})(typeof global !== "undefined" ? global : this.window || this.global, function() { | ||
"use strict"; | ||
const version = "0.1.5"; | ||
const version = "0.1.6"; | ||
/* HELPERS*/ | ||
/* HELPERS*/ | ||
/** | ||
* addEventListener shortcut | ||
* @param {HTMLElement} el | ||
* @param {String} type | ||
* @param {Function} callback | ||
* @return {Void} | ||
*/ | ||
const on = (el, type, callback) => { | ||
el.addEventListener(type, callback, false); | ||
}; | ||
/** | ||
* 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); | ||
}; | ||
/** | ||
* 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); | ||
/** | ||
* 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); | ||
} | ||
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"; | ||
/** | ||
* Rangeable | ||
* @param {String|HTMLElement} input | ||
* @param {Object} config | ||
*/ | ||
const Rangeable = function(input, config) { | ||
this.plugins = ["ruler"]; | ||
const defaultConfig = { | ||
type: "single", | ||
tooltips: "always", | ||
updateThrottle: 30, | ||
formatTooltip: (value => value), | ||
classes: { | ||
input: "rangeable-input", | ||
container: "rangeable-container", | ||
vertical: "rangeable-vertical", | ||
progress: "rangeable-progress", | ||
handle: "rangeable-handle", | ||
track: "rangeable-track", | ||
multiple: "rangeable-multiple", | ||
disabled: "rangeable-disabled", | ||
tooltips: "rangeable-tooltips", | ||
tooltip: "rangeable-tooltip", | ||
visible: "rangeable-tooltips--visible" | ||
} | ||
}; | ||
/** | ||
* 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); | ||
} | ||
}; | ||
// user has passed a CSS3 selector string | ||
if (typeof input === "string") { | ||
input = document.querySelector(input); | ||
} | ||
this.input = input; | ||
this.config = Object.assign({}, defaultConfig, config); | ||
this.mouseAxis = { | ||
x: "clientX", | ||
y: "clientY" | ||
}; | ||
this.trackSize = { | ||
x: "width", | ||
y: "height" | ||
}; | ||
this.trackPos = { | ||
x: "left", | ||
y: "top" | ||
}; | ||
this.lastPos = 0; | ||
this.double = | ||
this.config.type === "double" || Array.isArray(this.config.value); | ||
this.touch = | ||
"ontouchstart" in window || | ||
(window.DocumentTouch && document instanceof DocumentTouch); | ||
this.version = version; | ||
/** | ||
* 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: { | ||
input: "rangeable-input", | ||
container: "rangeable-container", | ||
vertical: "rangeable-vertical", | ||
progress: "rangeable-progress", | ||
handle: "rangeable-handle", | ||
track: "rangeable-track", | ||
multiple: "rangeable-multiple", | ||
disabled: "rangeable-disabled", | ||
tooltips: "rangeable-tooltips", | ||
tooltip: "rangeable-tooltip", | ||
visible: "rangeable-tooltips--visible" | ||
} | ||
}; | ||
this.init(); | ||
// user has passed a CSS3 selector string | ||
if (typeof input === "string") { | ||
input = document.querySelector(input); | ||
} | ||
this.onInit(); | ||
}; | ||
this.input = input; | ||
this.config = Object.assign({}, defaultConfig, config); | ||
this.mouseAxis = { | ||
x: "clientX", | ||
y: "clientY" | ||
/** | ||
* Initialise the instance | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.init = function() { | ||
if (!this.input.rangeable) { | ||
const props = { | ||
min: 0, | ||
max: 100, | ||
step: 1, | ||
value: this.input.value | ||
}; | ||
this.trackSize = { | ||
x: "width", | ||
y: "height" | ||
}; | ||
this.trackPos = { | ||
x: "left", | ||
y: "top" | ||
}; | ||
this.lastPos = 0; | ||
this.double = | ||
this.config.type === "double" || Array.isArray(this.config.value); | ||
this.touch = | ||
"ontouchstart" in window || | ||
(window.DocumentTouch && document instanceof DocumentTouch); | ||
this.version = version; | ||
this.init(); | ||
for (let prop in props) { | ||
// prop is missing, so add it | ||
if (!this.input[prop]) { | ||
this.input[prop] = props[prop]; | ||
} | ||
this.onInit(); | ||
}; | ||
// prop set in config | ||
if (this.config[prop] !== undefined) { | ||
this.input[prop] = this.config[prop]; | ||
} | ||
} | ||
/** | ||
* Initialise the instance | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.init = function() { | ||
if (!this.input.rangeable) { | ||
const props = { | ||
min: 0, | ||
max: 100, | ||
step: 1, | ||
value: this.input.value | ||
}; | ||
this.axis = !this.config.vertical ? "x" : "y"; | ||
for (let prop in props) { | ||
// prop is missing, so add it | ||
if (!this.input[prop]) { | ||
this.input[prop] = props[prop]; | ||
} | ||
this.input.rangeable = this; | ||
// prop set in config | ||
if (this.config[prop] !== undefined) { | ||
this.input[prop] = this.config[prop]; | ||
} | ||
if (this.double) { | ||
this.input.values = this.config.value ? | ||
this.config.value : | ||
[this.input.min, this.input.max]; | ||
this.input.defaultValues = this.input.values.slice(); | ||
} else { | ||
if (!this.input.defaultValue) { | ||
this.input.defaultValue = this.input.value; | ||
} | ||
} | ||
this.axis = !this.config.vertical ? "x" : "y"; | ||
this.render(); | ||
this.input.rangeable = this; | ||
this.initialised = true; | ||
} | ||
}; | ||
if (this.double) { | ||
this.input.values = this.config.value | ||
? this.config.value | ||
: [this.input.min, this.input.max]; | ||
this.input.defaultValues = this.input.values.slice(); | ||
} else { | ||
if (!this.input.defaultValue) { | ||
this.input.defaultValue = this.input.value; | ||
} | ||
} | ||
/** | ||
* Render the instance | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.render = function() { | ||
const o = this.config; | ||
const c = o.classes; | ||
this.render(); | ||
const container = createElement("div", c.container); | ||
const track = createElement("div", c.track); | ||
const progress = createElement("div", c.progress); | ||
this.initialised = true; | ||
} | ||
}; | ||
let handle = createElement("div", c.handle); | ||
let tooltip = createElement("div", c.tooltip); | ||
/** | ||
* Render the instance | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.render = function() { | ||
const o = this.config; | ||
const c = o.classes; | ||
this.input.tabIndex = -1; | ||
const container = createElement("div", c.container); | ||
const track = createElement("div", c.track); | ||
const progress = createElement("div", c.progress); | ||
if (this.double) { | ||
handle = [createElement("div", c.handle), createElement("div", c.handle)]; | ||
tooltip = []; | ||
let handle = createElement("div", c.handle); | ||
let tooltip = createElement("div", c.tooltip); | ||
for (let i = 0; i < 3; i++) tooltip[i] = createElement("div", c.tooltip); | ||
this.input.tabIndex = -1; | ||
handle.forEach((node, i) => { | ||
node.index = i; | ||
progress.appendChild(node); | ||
node.appendChild(tooltip[i]); | ||
node.tabIndex = 1; | ||
if (this.double) { | ||
handle = [createElement("div", c.handle), createElement("div", c.handle)]; | ||
tooltip = [ | ||
createElement("div", c.tooltip), | ||
createElement("div", c.tooltip), | ||
createElement("div", c.tooltip) | ||
]; | ||
handle.forEach((node, i) => { | ||
node.index = i; | ||
progress.appendChild(node); | ||
node.appendChild(tooltip[i]); | ||
node.tabIndex = 1; | ||
// locked handles? | ||
if (o.handles && o.handles[i]) { | ||
if (o.handles[i].locked && o.handles[i].locked === true) { | ||
node.locked = true; | ||
} | ||
// locked handles? | ||
if (o.controls && o.controls[i]) { | ||
if (o.controls[i].locked && o.controls[i].locked === true) { | ||
node.locked = true; | ||
} | ||
}); | ||
if (o.vertical) { | ||
progress.appendChild(handle[0]); | ||
} | ||
}); | ||
progress.appendChild(tooltip[2]); | ||
if (o.vertical) { | ||
progress.appendChild(handle[0]); | ||
} | ||
container.classList.add(c.multiple); | ||
} else { | ||
progress.appendChild(handle); | ||
handle.appendChild(tooltip); | ||
progress.appendChild(tooltip[2]); | ||
handle.tabIndex = 1; | ||
container.classList.add(c.multiple); | ||
} else { | ||
progress.appendChild(handle); | ||
handle.appendChild(tooltip); | ||
// locked handle? | ||
if (o.handle) { | ||
if (o.handle.locked && o.handle.locked === true) { | ||
handle.locked = true; | ||
} | ||
handle.tabIndex = 1; | ||
// locked handle? | ||
if (o.controls) { | ||
if (o.controls.locked && o.controls.locked === true) { | ||
handle.locked = true; | ||
} | ||
} | ||
} | ||
container.appendChild(track); | ||
container.appendChild(track); | ||
if (o.vertical) { | ||
container.classList.add(c.vertical); | ||
} | ||
if (o.vertical) { | ||
container.classList.add(c.vertical); | ||
} | ||
if (o.size) { | ||
container.style[this.trackSize[this.axis]] = !isNaN(o.size) | ||
? `${o.size}px` | ||
: o.size; | ||
} | ||
if (o.size) { | ||
container.style[this.trackSize[this.axis]] = !isNaN(o.size) ? | ||
`${o.size}px` : | ||
o.size; | ||
} | ||
if (o.tooltips) { | ||
container.classList.add(c.tooltips); | ||
if (o.tooltips) { | ||
container.classList.add(c.tooltips); | ||
if (typeof o.tooltips === "string" && o.tooltips === "always") { | ||
container.classList.add(c.visible); | ||
} | ||
if (typeof o.tooltips === "string" && o.tooltips === "always") { | ||
container.classList.add(c.visible); | ||
} | ||
} | ||
this.nodes = { | ||
container, | ||
track, | ||
progress, | ||
handle, | ||
tooltip | ||
}; | ||
this.nodes = { | ||
container, | ||
track, | ||
progress, | ||
handle, | ||
tooltip | ||
}; | ||
if (this.double) { | ||
this.nodes.buffer = []; | ||
const buffers = createElement("div", "rangeable-buffers"); | ||
if (this.double) { | ||
this.nodes.buffer = []; | ||
const buffers = createElement("div", "rangeable-buffers"); | ||
this.input.values.forEach((val, i) => { | ||
const buffer = createElement("div", "rangeable-buffer"); | ||
buffers.appendChild(buffer); | ||
this.nodes.buffer.push(buffer); | ||
this.input.values.forEach((val, i) => { | ||
const buffer = createElement("div", "rangeable-buffer"); | ||
buffers.appendChild(buffer); | ||
this.nodes.buffer.push(buffer); | ||
track.appendChild(buffers); | ||
track.appendChild(buffers); | ||
if (o.handles) { | ||
this.limits = [{}, {}]; | ||
if (o.handles[i].min !== undefined) { | ||
this.limits[i].min = o.handles[i].min; | ||
} | ||
if (o.handles[i].max !== undefined) { | ||
this.limits[i].max = o.handles[i].max; | ||
} | ||
if (o.controls) { | ||
this.limits = [{}, {}]; | ||
if (o.controls[i].min !== undefined) { | ||
this.limits[i].min = o.controls[i].min; | ||
} | ||
}); | ||
this.setLimits(o.handles); | ||
} else { | ||
const buffer = createElement("div", "rangeable-buffer"); | ||
if (o.controls[i].max !== undefined) { | ||
this.limits[i].max = o.controls[i].max; | ||
} | ||
} | ||
}); | ||
this.setLimits(o.controls); | ||
} else { | ||
const buffer = createElement("div", "rangeable-buffer"); | ||
track.appendChild(buffer); | ||
track.appendChild(buffer); | ||
this.nodes.buffer = buffer; | ||
this.nodes.buffer = buffer; | ||
track.appendChild(buffer); | ||
track.appendChild(buffer); | ||
if (o.handle) { | ||
this.limits = {}; | ||
if (o.handle.min !== undefined) { | ||
this.limits.min = o.handle.min; | ||
} | ||
if (o.handle.max !== undefined) { | ||
this.limits.max = o.handle.max; | ||
} | ||
if (o.controls) { | ||
this.limits = {}; | ||
if (o.controls.min !== undefined) { | ||
this.limits.min = o.controls.min; | ||
} | ||
this.setLimits(o.handle); | ||
if (o.controls.max !== undefined) { | ||
this.limits.max = o.controls.max; | ||
} | ||
} | ||
this.setLimits(o.controls); | ||
} | ||
track.appendChild(progress); | ||
track.appendChild(progress); | ||
this.input.parentNode.insertBefore(container, this.input); | ||
container.insertBefore(this.input, track); | ||
this.input.parentNode.insertBefore(container, this.input); | ||
container.insertBefore(this.input, track); | ||
this.input.classList.add(c.input); | ||
this.input.classList.add(c.input); | ||
this.bind(); | ||
this.bind(); | ||
this.update(); | ||
}; | ||
this.update(); | ||
}; | ||
/** | ||
* Reset the value(s) to default | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.reset = function() { | ||
if (this.double) { | ||
this.input.defaultValues.forEach(this.setValue, this); | ||
} else { | ||
this.setValue(this.input.defaultValue); | ||
} | ||
this.onEnd(); | ||
}; | ||
/** | ||
* Reset the value(s) to default | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.reset = function() { | ||
if (this.double) { | ||
this.input.defaultValues.forEach(this.setValue, this); | ||
} else { | ||
this.setValue(this.input.defaultValue); | ||
} | ||
this.onEnd(); | ||
}; | ||
/** | ||
* Set the value from the position of pointer over the track | ||
* @param {Object} e | ||
*/ | ||
Rangeable.prototype.setValueFromPosition = function(e) { | ||
const limits = this.getLimits(); | ||
const step = parseFloat(this.input.step); | ||
const rect = this.rects; | ||
const axis = this.touch | ||
? e.touches[0][this.mouseAxis[this.axis]] | ||
: e[this.mouseAxis[this.axis]]; | ||
const point = axis - this.rects.container[this.trackPos[this.axis]]; | ||
const size = rect.container[this.trackSize[this.axis]]; | ||
/** | ||
* Set the value from the position of pointer over the track | ||
* @param {Object} e | ||
*/ | ||
Rangeable.prototype.setValueFromPosition = function(e) { | ||
const limits = this.getLimits(); | ||
const step = parseFloat(this.input.step); | ||
const rect = this.rects; | ||
const axis = this.touch ? | ||
e.touches[0][this.mouseAxis[this.axis]] : | ||
e[this.mouseAxis[this.axis]]; | ||
const point = axis - this.rects.container[this.trackPos[this.axis]]; | ||
const size = rect.container[this.trackSize[this.axis]]; | ||
if (e.type === "mousedown") { | ||
if ( | ||
(!this.double && this.nodes.handle.contains(e.target)) || | ||
(this.double && | ||
(this.nodes.handle[0].contains(e.target) || | ||
this.nodes.handle[1].contains(e.target))) | ||
) { | ||
return false; | ||
} | ||
if (e.type === "mousedown") { | ||
if ( | ||
(!this.double && this.nodes.handle.contains(e.target)) || | ||
(this.double && | ||
(this.nodes.handle[0].contains(e.target) || | ||
this.nodes.handle[1].contains(e.target))) | ||
) { | ||
return false; | ||
} | ||
} | ||
// get the position of the cursor over the bar as a percentage | ||
let position = this.config.vertical | ||
? (size - point) / size * 100 | ||
: point / size * 100; | ||
// get the position of the cursor over the bar as a percentage | ||
let position = this.config.vertical ? | ||
(size - point) / size * 100 : | ||
point / size * 100; | ||
// work out the value from the position | ||
let val = position * (limits.max - limits.min) / 100 + limits.min; | ||
// work out the value from the position | ||
let val = position * (limits.max - limits.min) / 100 + limits.min; | ||
// apply granularity (step) | ||
val = Math.ceil(val / step) * step; | ||
// apply granularity (step) | ||
val = Math.ceil(val / step) * step; | ||
if (axis >= this.lastPos) { | ||
val -= step; | ||
} | ||
if (axis >= this.lastPos) { | ||
val -= step; | ||
} | ||
// prevent change event from firing if slider hasn't moved | ||
if (parseFloat(val) === parseFloat(this.startValue)) { | ||
return false; | ||
} | ||
// prevent change event from firing if slider hasn't moved | ||
if (parseFloat(val) === parseFloat(this.startValue)) { | ||
return false; | ||
} | ||
let index = false; | ||
let index = false; | ||
if (this.double) { | ||
index = this.activeHandle.index; | ||
} | ||
if (this.double) { | ||
index = this.activeHandle.index; | ||
} | ||
val = this.limit(val, index); | ||
val = this.limit(val, index); | ||
this.setValue(val, index); | ||
}; | ||
this.setValue(val, index); | ||
}; | ||
/** | ||
* Mousedown / touchstart callback | ||
* @param {Object} e | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.start = function(e) { | ||
e.preventDefault(); | ||
/** | ||
* Mousedown / touchstart callback | ||
* @param {Object} e | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.start = function(e) { | ||
e.preventDefault(); | ||
this.startValue = this.getValue(); | ||
this.startValue = this.getValue(); | ||
this.onStart(); | ||
// show the tip now so we can get the dimensions later | ||
this.nodes.container.classList.add("dragging"); | ||
this.onStart(); | ||
// show the tip now so we can get the dimensions later | ||
this.nodes.container.classList.add("dragging"); | ||
this.recalculate(); | ||
this.recalculate(); | ||
this.activeHandle = this.getHandle(e); | ||
this.activeHandle = this.getHandle(e); | ||
if (!this.activeHandle) { | ||
return false; | ||
} | ||
if (!this.activeHandle) { | ||
return false; | ||
} | ||
this.activeHandle.classList.add("active"); | ||
this.activeHandle.classList.add("active"); | ||
this.setValueFromPosition(e); | ||
this.setValueFromPosition(e); | ||
if (this.touch) { | ||
on(document, "touchmove", this.events.move); | ||
on(document, "touchend", this.events.stop); | ||
on(document, "touchcancel", this.events.stop); | ||
} else { | ||
on(document, "mousemove", this.events.move); | ||
on(document, "mouseup", this.events.stop); | ||
} | ||
}; | ||
if (this.touch) { | ||
on(document, "touchmove", this.events.move); | ||
on(document, "touchend", this.events.stop); | ||
on(document, "touchcancel", this.events.stop); | ||
} else { | ||
on(document, "mousemove", this.events.move); | ||
on(document, "mouseup", this.events.stop); | ||
} | ||
}; | ||
/** | ||
* Mousemove / touchmove callback | ||
* @param {Object} e | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.move = function(e) { | ||
this.setValueFromPosition(e); | ||
this.lastPos = this.touch | ||
? e.touches[0][this.mouseAxis[this.axis]] | ||
: e[this.mouseAxis[this.axis]]; | ||
}; | ||
/** | ||
* Mousemove / touchmove callback | ||
* @param {Object} e | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.move = function(e) { | ||
this.setValueFromPosition(e); | ||
this.lastPos = this.touch ? | ||
e.touches[0][this.mouseAxis[this.axis]] : | ||
e[this.mouseAxis[this.axis]]; | ||
}; | ||
/** | ||
* Mouseup / touchend callback | ||
* @param {Object} e | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.stop = function(e) { | ||
this.stopValue = this.getValue(); | ||
/** | ||
* Mouseup / touchend callback | ||
* @param {Object} e | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.stop = function(e) { | ||
this.stopValue = this.getValue(); | ||
this.nodes.container.classList.remove("dragging"); | ||
this.nodes.container.classList.remove("dragging"); | ||
this.onEnd(); | ||
this.onEnd(); | ||
this.activeHandle.classList.remove("active"); | ||
this.activeHandle = false; | ||
this.activeHandle.classList.remove("active"); | ||
this.activeHandle = false; | ||
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); | ||
} | ||
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); | ||
} | ||
if (this.startValue !== this.stopValue) { | ||
this.input.dispatchEvent(new Event("change")); | ||
if (this.startValue !== this.stopValue) { | ||
this.input.dispatchEvent(new Event("change")); | ||
} | ||
this.startValue = null; | ||
}; | ||
/** | ||
* Keydown callback | ||
* @param {Object} e | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.keydown = function(e) { | ||
const step = index => { | ||
switch (e.key) { | ||
case "ArrowRight": | ||
case "ArrowUp": | ||
this.stepUp(index); | ||
break; | ||
case "ArrowLeft": | ||
case "ArrowDown": | ||
this.stepDown(index); | ||
break; | ||
} | ||
this.startValue = null; | ||
}; | ||
/** | ||
* Keydown callback | ||
* @param {Object} e | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.keydown = function(e) { | ||
const step = index => { | ||
switch (e.key) { | ||
case "ArrowRight": | ||
case "ArrowUp": | ||
this.stepUp(index); | ||
break; | ||
case "ArrowLeft": | ||
case "ArrowDown": | ||
this.stepDown(index); | ||
break; | ||
if (this.double) { | ||
this.nodes.handle.forEach(node => { | ||
if (node === document.activeElement) { | ||
step(node.index); | ||
} | ||
}; | ||
if (this.double) { | ||
this.nodes.handle.forEach(node => { | ||
if (node === document.activeElement) { | ||
step(node.index); | ||
} | ||
}); | ||
} else { | ||
if (this.nodes.handle === document.activeElement) { | ||
step(); | ||
} | ||
}); | ||
} else { | ||
if (this.nodes.handle === document.activeElement) { | ||
step(); | ||
} | ||
}; | ||
} | ||
}; | ||
/** | ||
* Increase the value by step | ||
* @param {Number} index | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.stepUp = function(index) { | ||
const step = parseFloat(this.input.step); | ||
/** | ||
* Increase the value by step | ||
* @param {Number} index | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.stepUp = function(index) { | ||
const step = parseFloat(this.input.step); | ||
let val = this.getValue(); | ||
let val = this.getValue(); | ||
if (this.double && index !== undefined) { | ||
val = val[index]; | ||
} | ||
if (this.double && index !== undefined) { | ||
val = val[index]; | ||
} | ||
let newval = this.limit(parseFloat(val) + step, index); | ||
let newval = this.limit(parseFloat(val) + step, index); | ||
this.setValue(newval, index); | ||
}; | ||
this.setValue(newval, index); | ||
}; | ||
/** | ||
* Decrease the value by step | ||
* @param {Number} index | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.stepDown = function(index) { | ||
const step = parseFloat(this.input.step); | ||
/** | ||
* Decrease the value by step | ||
* @param {Number} index | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.stepDown = function(index) { | ||
const step = parseFloat(this.input.step); | ||
let val = this.getValue(); | ||
let val = this.getValue(); | ||
if (this.double && index !== undefined) { | ||
val = val[index]; | ||
} | ||
if (this.double && index !== undefined) { | ||
val = val[index]; | ||
} | ||
let newval = this.limit(parseFloat(val) - step, index); | ||
let newval = this.limit(parseFloat(val) - step, index); | ||
this.setValue(newval, index); | ||
}; | ||
this.setValue(newval, 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; | ||
const limits = this.getLimits(); | ||
/** | ||
* 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; | ||
const limits = this.getLimits(); | ||
value = parseFloat(value); | ||
value = parseFloat(value); | ||
if (this.double && index !== undefined) { | ||
if (!index && value > el.values[1]) { | ||
value = el.values[1]; | ||
} else if (index > 0 && value < el.values[0]) { | ||
value = el.values[0]; | ||
} | ||
if (this.double && index !== undefined) { | ||
if (!index && value > el.values[1]) { | ||
value = el.values[1]; | ||
} else if (index > 0 && value < el.values[0]) { | ||
value = el.values[0]; | ||
} | ||
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; | ||
} | ||
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 (this.limits) { | ||
if (value > this.limits.max) { | ||
value = this.limits.max; | ||
} else if (value < this.limits.min) { | ||
value = this.limits.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; | ||
} | ||
} | ||
} | ||
if (value > limits.max) { | ||
value = limits.max; | ||
} else if (value < limits.min) { | ||
value = limits.min; | ||
} else { | ||
if (this.limits) { | ||
if (value > this.limits.max) { | ||
value = this.limits.max; | ||
} else if (value < this.limits.min) { | ||
value = this.limits.min; | ||
} | ||
} | ||
} | ||
value = parseFloat(value); | ||
if (value > limits.max) { | ||
value = limits.max; | ||
} else if (value < limits.min) { | ||
value = limits.min; | ||
} | ||
value = value.toFixed(this.accuracy); | ||
value = parseFloat(value); | ||
return value; | ||
}; | ||
value = value.toFixed(this.accuracy); | ||
/** | ||
* Recache dimensions | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.recalculate = function() { | ||
let handle = []; | ||
return value; | ||
}; | ||
if (this.double) { | ||
this.nodes.handle.forEach((node, i) => { | ||
handle[i] = node.getBoundingClientRect(); | ||
}); | ||
} else { | ||
handle = this.nodes.handle.getBoundingClientRect(); | ||
} | ||
/** | ||
* Recache dimensions | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.recalculate = function() { | ||
let handle = []; | ||
this.rects = { | ||
handle: handle, | ||
container: this.nodes.container.getBoundingClientRect() | ||
}; | ||
if (this.double) { | ||
this.nodes.handle.forEach((node, i) => { | ||
handle[i] = node.getBoundingClientRect(); | ||
}); | ||
} else { | ||
handle = this.nodes.handle.getBoundingClientRect(); | ||
} | ||
this.rects = { | ||
handle: handle, | ||
container: this.nodes.container.getBoundingClientRect() | ||
}; | ||
}; | ||
/** | ||
* Update the instance | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.update = function() { | ||
this.recalculate(); | ||
/** | ||
* Update the instance | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.update = function() { | ||
this.recalculate(); | ||
this.accuracy = 0; | ||
this.accuracy = 0; | ||
// detect float | ||
if (this.input.step.includes(".")) { | ||
this.accuracy = (this.input.step.split(".")[1] || []).length; | ||
} | ||
// detect float | ||
if (this.input.step.includes(".")) { | ||
this.accuracy = (this.input.step.split(".")[1] || []).length; | ||
} | ||
const value = this.getValue(); | ||
const limits = this.getLimits(); | ||
const size = this.rects.container[this.trackSize[this.axis]]; | ||
const value = this.getValue(); | ||
const limits = this.getLimits(); | ||
const size = this.rects.container[this.trackSize[this.axis]]; | ||
const setStyle = (el, offset, m) => { | ||
el.style[this.config.vertical ? "bottom" : "left"] = `${offset}px`; | ||
el.style[this.trackSize[this.axis]] = `${m / limits.max * size - offset}px`; | ||
}; | ||
const setStyle = (el, offset, m) => { | ||
el.style[this.config.vertical ? "bottom" : "left"] = `${offset}px`; | ||
el.style[this.trackSize[this.axis]] = `${m / limits.max * size - offset}px`; | ||
}; | ||
if (this.double) { | ||
// set buffers | ||
if (this.limits) { | ||
this.limits.forEach((o, i) => { | ||
setStyle(this.nodes.buffer[i], o.min / limits.max * size, o.max); | ||
}); | ||
} | ||
this.input.values.forEach((val, i) => { | ||
this.setValue(this.limit(val, i), i); | ||
if (this.double) { | ||
// set buffers | ||
if (this.limits) { | ||
this.limits.forEach((o, i) => { | ||
setStyle(this.nodes.buffer[i], o.min / limits.max * size, o.max); | ||
}); | ||
} else { | ||
// set buffer | ||
if (this.limits) { | ||
setStyle( | ||
this.nodes.buffer, | ||
this.limits.min / limits.max * size, | ||
this.limits.max | ||
); | ||
} | ||
this.setValue(this.limit(value)); | ||
} | ||
}; | ||
/** | ||
* Get the current value(s) | ||
* @return {Number|Array} | ||
*/ | ||
Rangeable.prototype.getValue = function() { | ||
return this.double ? this.input.values : this.input.value; | ||
}; | ||
this.input.values.forEach((val, i) => { | ||
this.setValue(this.limit(val, i), i); | ||
}); | ||
} else { | ||
// set buffer | ||
if (this.limits) { | ||
setStyle( | ||
this.nodes.buffer, | ||
this.limits.min / limits.max * size, | ||
this.limits.max | ||
); | ||
} | ||
this.setValue(this.limit(value)); | ||
} | ||
}; | ||
/** | ||
* Set the current value(s) | ||
* @param {Number} value | ||
* @param {Number} index | ||
*/ | ||
Rangeable.prototype.setValue = function(value, index) { | ||
const rects = this.rects; | ||
const nodes = this.nodes; | ||
/** | ||
* Get the current value(s) | ||
* @return {Number|Array} | ||
*/ | ||
Rangeable.prototype.getValue = function() { | ||
return this.double ? this.input.values : this.input.value; | ||
}; | ||
let handle = nodes.handle; | ||
/** | ||
* Set the current value(s) | ||
* @param {Number} value | ||
* @param {Number} index | ||
*/ | ||
Rangeable.prototype.setValue = function(value, index) { | ||
const rects = this.rects; | ||
const nodes = this.nodes; | ||
if (this.double) { | ||
if (index === undefined) { | ||
return false; | ||
} | ||
let handle = nodes.handle; | ||
handle = this.activeHandle ? this.activeHandle : nodes.handle[index]; | ||
if (this.double) { | ||
if (index === undefined) { | ||
return false; | ||
} | ||
if (value === undefined) { | ||
value = this.input.value; | ||
} | ||
handle = this.activeHandle ? this.activeHandle : nodes.handle[index]; | ||
} | ||
value = this.limit(value, index); | ||
if (value === undefined) { | ||
value = this.input.value; | ||
} | ||
const doChange = | ||
this.initialised && (value !== this.input.value || this.nativeEvent); | ||
value = this.limit(value, index); | ||
// update the value | ||
if (this.double) { | ||
const values = this.input.values; | ||
values[index] = value; | ||
const doChange = | ||
this.initialised && (value !== this.input.value || this.nativeEvent); | ||
if (this.config.tooltips) { | ||
// update the node so we can get the width / height | ||
nodes.tooltip[index].textContent = value; | ||
const format = this.config.formatTooltip; | ||
// update the value | ||
if (this.double) { | ||
const values = this.input.values; | ||
values[index] = value; | ||
// check if tips are intersecting... | ||
const a = nodes.tooltip[0].getBoundingClientRect(); | ||
const b = nodes.tooltip[1].getBoundingClientRect(); | ||
const intersect = !( | ||
a.right < b.left || | ||
a.left > b.right || | ||
a.bottom < b.top || | ||
a.top > b.bottom | ||
); | ||
if (this.config.tooltips) { | ||
// update the node so we can get the width / height | ||
nodes.tooltip[index].textContent = format.call(this, value); | ||
// ... and set the className where appropriate | ||
nodes.container.classList.toggle("combined-tooltip", intersect); | ||
// check if tips are intersecting... | ||
const a = nodes.tooltip[0].getBoundingClientRect(); | ||
const b = nodes.tooltip[1].getBoundingClientRect(); | ||
const intersect = !( | ||
a.right < b.left || | ||
a.left > b.right || | ||
a.bottom < b.top || | ||
a.top > b.bottom | ||
); | ||
if (intersect) { | ||
// Format the combined tooltip. | ||
// Only show single value if they both match, otherwise show both seperated by a hyphen | ||
nodes.tooltip[2].textContent = | ||
values[0] === values[1] ? values[0] : `${values[0]} - ${values[1]}`; | ||
} | ||
// ... and set the className where appropriate | ||
nodes.container.classList.toggle("combined-tooltip", intersect); | ||
if (intersect) { | ||
// Format the combined tooltip. | ||
// Only show single value if they both match, otherwise show both seperated by a hyphen | ||
nodes.tooltip[2].textContent = | ||
values[0] === values[1] ? format.call(this, values[0]) : `${format.call(this, values[0])} - ${format.call(this, values[1])}`; | ||
} | ||
} else { | ||
this.input.value = value; | ||
nodes.tooltip.textContent = value; | ||
} | ||
} else { | ||
this.input.value = value; | ||
nodes.tooltip.textContent = format.call(this, value); | ||
} | ||
// set bar size | ||
this.setPosition(value, index); | ||
// set bar size | ||
this.setPosition(value, index); | ||
if (doChange) { | ||
this.onChange(); | ||
if (doChange) { | ||
this.onChange(); | ||
if (!this.nativeEvent) { | ||
this.input.dispatchEvent(new Event("input")); | ||
} | ||
this.nativeEvent = false; | ||
if (!this.nativeEvent) { | ||
this.input.dispatchEvent(new Event("input")); | ||
} | ||
}; | ||
/** | ||
* Native callback | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.native = function() { | ||
this.nativeEvent = true; | ||
this.nativeEvent = false; | ||
} | ||
}; | ||
this.setValue(); | ||
}; | ||
/** | ||
* Native callback | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.native = function() { | ||
this.nativeEvent = true; | ||
Rangeable.prototype.getLimits = function() { | ||
return { | ||
min: parseFloat(this.input.min), | ||
max: parseFloat(this.input.max) | ||
}; | ||
this.setValue(); | ||
}; | ||
Rangeable.prototype.getLimits = function() { | ||
return { | ||
min: parseFloat(this.input.min), | ||
max: parseFloat(this.input.max) | ||
}; | ||
}; | ||
/** | ||
* Set the buffer | ||
* @param {[type]} value [description] | ||
*/ | ||
Rangeable.prototype.setLimits = function(config) { | ||
if (config === undefined) return false; | ||
/** | ||
* Set the buffer | ||
* @param {[type]} value [description] | ||
*/ | ||
Rangeable.prototype.setLimits = function(config) { | ||
if (config === undefined) return false; | ||
if (!this.limits) { | ||
this.limits = config; | ||
if (!this.limits) { | ||
this.limits = config; | ||
} | ||
const setLimit = (limit, o) => { | ||
if (o.min !== undefined) { | ||
limit.min = o.min; | ||
} | ||
if (o.max !== undefined) { | ||
limit.max = o.max; | ||
} | ||
}; | ||
const setLimit = (limit, o) => { | ||
if (o.min !== undefined) { | ||
limit.min = o.min; | ||
} | ||
if (o.max !== undefined) { | ||
limit.max = o.max; | ||
} | ||
}; | ||
if (this.double) { | ||
config.forEach((o, i) => { | ||
setLimit(this.limits[i], o); | ||
}); | ||
} else { | ||
setLimit(this.limits, config); | ||
} | ||
if (this.double) { | ||
config.forEach((o, i) => { | ||
setLimit(this.limits[i], o); | ||
}); | ||
} else { | ||
setLimit(this.limits, config); | ||
} | ||
this.update(); | ||
}; | ||
this.update(); | ||
}; | ||
/** | ||
* Set the postion / size of the progress bar. | ||
* @param {[type]} value [description] | ||
*/ | ||
Rangeable.prototype.setPosition = function(value) { | ||
let width; | ||
/** | ||
* Set the postion / size of the progress bar. | ||
* @param {[type]} value [description] | ||
*/ | ||
Rangeable.prototype.setPosition = function(value) { | ||
let width; | ||
if (this.double) { | ||
let start = this.getPosition(this.input.values[0]); | ||
let end = this.getPosition(this.input.values[1]); | ||
if (this.double) { | ||
let start = this.getPosition(this.input.values[0]); | ||
let end = this.getPosition(this.input.values[1]); | ||
// set the start point of the bar | ||
this.nodes.progress.style[ | ||
this.config.vertical ? "bottom" : "left" | ||
] = `${start}px`; | ||
// set the start point of the bar | ||
this.nodes.progress.style[ | ||
this.config.vertical ? "bottom" : "left" | ||
] = `${start}px`; | ||
width = end - start; | ||
} else { | ||
width = this.getPosition(); | ||
} | ||
width = end - start; | ||
} else { | ||
width = this.getPosition(); | ||
} | ||
// set the end point of the bar | ||
this.nodes.progress.style[this.trackSize[this.axis]] = `${width}px`; | ||
}; | ||
// set the end point of the bar | ||
this.nodes.progress.style[this.trackSize[this.axis]] = `${width}px`; | ||
}; | ||
/** | ||
* Get the position along the track from a value. | ||
* @param {Number} value | ||
* @return {Number} | ||
*/ | ||
Rangeable.prototype.getPosition = function(value) { | ||
if (value === undefined) { | ||
value = this.input.value; | ||
} | ||
const limits = this.getLimits(); | ||
/** | ||
* Get the position along the track from a value. | ||
* @param {Number} value | ||
* @return {Number} | ||
*/ | ||
Rangeable.prototype.getPosition = function(value) { | ||
if (value === undefined) { | ||
value = this.input.value; | ||
} | ||
const limits = this.getLimits(); | ||
return ( | ||
(value - limits.min) / | ||
(limits.max - limits.min) * | ||
this.rects.container[this.trackSize[this.axis]] | ||
); | ||
}; | ||
return ( | ||
(value - limits.min) / | ||
(limits.max - limits.min) * | ||
this.rects.container[this.trackSize[this.axis]] | ||
); | ||
}; | ||
/** | ||
* Get the correct handle on mousedown / touchstart | ||
* @param {Object} e | ||
* @return {Boolean|HTMLElement} | ||
*/ | ||
Rangeable.prototype.getHandle = function(e) { | ||
if (!this.double) { | ||
return this.nodes.handle.locked ? false : this.nodes.handle; | ||
} | ||
/** | ||
* Get the correct handle on mousedown / touchstart | ||
* @param {Object} e | ||
* @return {Boolean|HTMLElement} | ||
*/ | ||
Rangeable.prototype.getHandle = function(e) { | ||
if (!this.double) { | ||
return this.nodes.handle.locked ? false : this.nodes.handle; | ||
const r = this.rects; | ||
const distA = Math.abs( | ||
e[this.mouseAxis[this.axis]] - r.handle[0][this.trackPos[this.axis]] | ||
); | ||
const distB = Math.abs( | ||
e[this.mouseAxis[this.axis]] - r.handle[1][this.trackPos[this.axis]] | ||
); | ||
let handle = e.target.closest(`.${this.config.classes.handle}`); | ||
if (!handle) { | ||
if (distA > distB) { | ||
handle = this.nodes.handle[1]; | ||
} else { | ||
handle = this.nodes.handle[0]; | ||
} | ||
} | ||
const r = this.rects; | ||
const distA = Math.abs( | ||
e[this.mouseAxis[this.axis]] - r.handle[0][this.trackPos[this.axis]] | ||
return handle.locked ? false : handle; | ||
}; | ||
/** | ||
* Enable the instance | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.enable = function() { | ||
if (this.input.disabled) { | ||
on( | ||
this.nodes.container, | ||
this.touch ? "touchstart" : "mousedown", | ||
this.events.start | ||
); | ||
const distB = Math.abs( | ||
e[this.mouseAxis[this.axis]] - r.handle[1][this.trackPos[this.axis]] | ||
); | ||
let handle = e.target.closest(`.${this.config.classes.handle}`); | ||
if (!handle) { | ||
if (distA > distB) { | ||
handle = this.nodes.handle[1]; | ||
} else { | ||
handle = this.nodes.handle[0]; | ||
} | ||
if (this.double) { | ||
this.nodes.handle.forEach(el => (el.tabIndex = 1)); | ||
} else { | ||
this.nodes.handle.tabIndex = 1; | ||
} | ||
return handle.locked ? false : handle; | ||
}; | ||
this.nodes.container.classList.remove(this.config.classes.disabled); | ||
/** | ||
* Enable the instance | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.enable = function() { | ||
if (this.input.disabled) { | ||
on( | ||
this.nodes.container, | ||
this.touch ? "touchstart" : "mousedown", | ||
this.events.start | ||
); | ||
this.input.disabled = false; | ||
} | ||
}; | ||
if (this.double) { | ||
this.nodes.handle.forEach(el => (el.tabIndex = 1)); | ||
} else { | ||
this.nodes.handle.tabIndex = 1; | ||
} | ||
/** | ||
* Disable the instance | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.disable = function() { | ||
if (!this.input.disabled) { | ||
off( | ||
this.nodes.container, | ||
this.touch ? "touchstart" : "mousedown", | ||
this.events.start | ||
); | ||
this.nodes.container.classList.remove(this.config.classes.disabled); | ||
this.input.disabled = false; | ||
if (this.double) { | ||
this.nodes.handle.forEach(el => el.removeAttribute("tabindex")); | ||
} else { | ||
this.nodes.handle.removeAttribute("tabindex"); | ||
} | ||
}; | ||
/** | ||
* Disable the instance | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.disable = function() { | ||
if (!this.input.disabled) { | ||
off( | ||
this.nodes.container, | ||
this.touch ? "touchstart" : "mousedown", | ||
this.events.start | ||
); | ||
this.nodes.container.classList.add(this.config.classes.disabled); | ||
if (this.double) { | ||
this.nodes.handle.forEach(el => el.removeAttribute("tabindex")); | ||
} else { | ||
this.nodes.handle.removeAttribute("tabindex"); | ||
} | ||
this.input.disabled = true; | ||
} | ||
}; | ||
this.nodes.container.classList.add(this.config.classes.disabled); | ||
/** | ||
* Add event listeners | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.bind = function() { | ||
this.events = {}; | ||
const events = [ | ||
"start", | ||
"move", | ||
"stop", | ||
"update", | ||
"reset", | ||
"native", | ||
"keydown" | ||
]; | ||
this.input.disabled = true; | ||
} | ||
}; | ||
// bind so we can remove later | ||
events.forEach(event => { | ||
this.events[event] = this[event].bind(this); | ||
}); | ||
/** | ||
* Add event listeners | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.bind = function() { | ||
this.events = {}; | ||
const events = [ | ||
"start", | ||
"move", | ||
"stop", | ||
"update", | ||
"reset", | ||
"native", | ||
"keydown" | ||
]; | ||
this.events.scroll = throttle( | ||
this.events.update, | ||
this.config.updateThrottle | ||
); | ||
this.events.resize = throttle( | ||
this.events.update, | ||
this.config.updateThrottle | ||
); | ||
// bind so we can remove later | ||
events.forEach(event => { | ||
this.events[event] = this[event].bind(this); | ||
}); | ||
// throttle the scroll callback for performance | ||
on(document, "scroll", this.events.scroll); | ||
this.events.scroll = throttle( | ||
this.events.update, | ||
this.config.updateThrottle | ||
); | ||
this.events.resize = throttle( | ||
this.events.update, | ||
this.config.updateThrottle | ||
); | ||
// throttle the resize callback for performance | ||
on(window, "resize", this.events.resize); | ||
// throttle the scroll callback for performance | ||
on(document, "scroll", this.events.scroll); | ||
// key control | ||
on(document, "keydown", this.events.keydown); | ||
// throttle the resize callback for performance | ||
on(window, "resize", this.events.resize); | ||
// touchstart/mousedown | ||
on( | ||
this.nodes.container, | ||
this.touch ? "touchstart" : "mousedown", | ||
this.events.start | ||
); | ||
// key control | ||
on(document, "keydown", this.events.keydown); | ||
// listen for native input to allow keyboard control on focus | ||
on(this.input, "input", this.events.native); | ||
// touchstart/mousedown | ||
on( | ||
this.nodes.container, | ||
this.touch ? "touchstart" : "mousedown", | ||
this.events.start | ||
); | ||
// detect form reset | ||
if (this.input.form) { | ||
on(this.input.form, "reset", this.events.reset); | ||
} | ||
}; | ||
// listen for native input to allow keyboard control on focus | ||
on(this.input, "input", this.events.native); | ||
/** | ||
* Remove event listeners | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.unbind = function() { | ||
// throttle the scroll callback for performance | ||
off(document, "scroll", this.events.scroll); | ||
// detect form reset | ||
if (this.input.form) { | ||
on(this.input.form, "reset", this.events.reset); | ||
} | ||
}; | ||
// throttle the resize callback for performance | ||
off(window, "resize", this.events.resize); | ||
/** | ||
* Remove event listeners | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.unbind = function() { | ||
// throttle the scroll callback for performance | ||
off(document, "scroll", this.events.scroll); | ||
off(document, "keydown", this.events.keydown); | ||
// throttle the resize callback for performance | ||
off(window, "resize", this.events.resize); | ||
off( | ||
this.nodes.container, | ||
this.touch ? "touchstart" : "mousedown", | ||
this.events.start | ||
); | ||
off(document, "keydown", this.events.keydown); | ||
// listen for native input to allow keyboard control on focus | ||
off(this.input, "input", this.events.native); | ||
off( | ||
this.nodes.container, | ||
this.touch ? "touchstart" : "mousedown", | ||
this.events.start | ||
); | ||
// detect form reset | ||
if (this.input.form) { | ||
off(this.input.form, "reset", this.events.reset); | ||
} | ||
// listen for native input to allow keyboard control on focus | ||
off(this.input, "input", this.events.native); | ||
this.events = null; | ||
}; | ||
// detect form reset | ||
if (this.input.form) { | ||
off(this.input.form, "reset", this.events.reset); | ||
} | ||
/** | ||
* Destroy the instance | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.destroy = function() { | ||
if (this.input.rangeable) { | ||
// remove all event events | ||
this.unbind(); | ||
this.events = null; | ||
}; | ||
// remove the className from the input | ||
this.input.classList.remove(this.config.classes.input); | ||
/** | ||
* Destroy the instance | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.destroy = function() { | ||
if (this.input.rangeable) { | ||
// remove all event events | ||
this.unbind(); | ||
// kill all nodes | ||
this.nodes.container.parentNode.replaceChild( | ||
this.input, | ||
this.nodes.container | ||
); | ||
// remove the className from the input | ||
this.input.classList.remove(this.config.classes.input); | ||
// remove the reference from the input | ||
delete this.input.rangeable; | ||
// kill all nodes | ||
this.nodes.container.parentNode.replaceChild( | ||
this.input, | ||
this.nodes.container | ||
); | ||
this.initialised = false; | ||
} | ||
}; | ||
// remove the reference from the input | ||
delete this.input.rangeable; | ||
/** | ||
* onInit callback | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.onInit = function() { | ||
if (isFunction(this.config.onInit)) { | ||
this.config.onInit.call(this, this.getValue()); | ||
} | ||
}; | ||
this.initialised = false; | ||
} | ||
}; | ||
/** | ||
* onStart callback | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.onStart = function() { | ||
if (isFunction(this.config.onStart)) { | ||
this.config.onStart.call(this, this.getValue()); | ||
} | ||
}; | ||
/** | ||
* onInit callback | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.onInit = function() { | ||
if (isFunction(this.config.onInit)) { | ||
this.config.onInit.call(this, this.getValue()); | ||
} | ||
}; | ||
/** | ||
* onChange callback | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.onChange = function() { | ||
if (isFunction(this.config.onChange)) { | ||
this.config.onChange.call(this, this.getValue()); | ||
} | ||
}; | ||
/** | ||
* onStart callback | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.onStart = function() { | ||
if (isFunction(this.config.onStart)) { | ||
this.config.onStart.call(this, this.getValue()); | ||
} | ||
}; | ||
/** | ||
* onEnd callback | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.onEnd = function() { | ||
if (isFunction(this.config.onEnd)) { | ||
this.config.onEnd.call(this, this.getValue()); | ||
} | ||
}; | ||
/** | ||
* onChange callback | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.onChange = function() { | ||
if (isFunction(this.config.onChange)) { | ||
this.config.onChange.call(this, this.getValue()); | ||
} | ||
}; | ||
/** | ||
* onEnd callback | ||
* @return {Void} | ||
*/ | ||
Rangeable.prototype.onEnd = function() { | ||
if (isFunction(this.config.onEnd)) { | ||
this.config.onEnd.call(this, this.getValue()); | ||
} | ||
}; | ||
return Rangeable; | ||
} | ||
); | ||
return Rangeable; | ||
}); |
Sorry, the diff of this file is not supported yet
277455
922