├── .gitattributes ├── range-slider.html ├── range-slider.min.css ├── range-slider.replace.html ├── range-slider.custom-range.html ├── range-slider.css ├── LICENSE ├── range-slider.test.html ├── range-slider.multiple-range.html ├── range-slider.custom.html ├── range-slider.min.js ├── README.md ├── index.html ├── range-slider.tip.html └── range-slider.js /.gitattributes: -------------------------------------------------------------------------------- 1 | * linguist-vendored 2 | *.js linguist-vendored=false 3 | -------------------------------------------------------------------------------- /range-slider.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Range Slider 7 | 8 | 9 | 10 |

11 |

12 | 13 | 19 | 20 | -------------------------------------------------------------------------------- /range-slider.min.css: -------------------------------------------------------------------------------- 1 | .range-slider{margin:0 5px 10px}.range-slider-track{width:auto;height:20px;margin:0 auto;position:relative;cursor:e-resize}.range-slider-track:before{content:"";display:block;position:absolute;top:9px;left:0;width:100%;height:2px;background-color:#000}.range-slider-track .dragger{display:block;width:10px;height:inherit;position:relative;z-index:2;background-color:red;cursor:inherit}.range-slider-vertical{display:inline-block;vertical-align:middle;margin:5px 10px 5px 0}.range-slider-vertical .range-slider-track{cursor:n-resize;width:20px;height:100px}.range-slider-vertical .range-slider-track:before{top:0;right:auto;left:9px;width:2px;height:100%}.range-slider-vertical .range-slider-track .dragger{width:inherit;height:10px} -------------------------------------------------------------------------------- /range-slider.replace.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Range Slider 7 | 8 | 9 | 10 | 11 |

12 |

13 | 14 | 24 | 25 | -------------------------------------------------------------------------------- /range-slider.custom-range.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Range Slider 7 | 8 | 9 | 10 |

Min: 2, Max: 40, Initial: 10

11 |

12 |

13 | 14 | 31 | 32 | -------------------------------------------------------------------------------- /range-slider.css: -------------------------------------------------------------------------------- 1 | .range-slider {margin:0 5px 10px} 2 | .range-slider-track { 3 | width:auto; 4 | height:20px; 5 | margin:0 auto; 6 | position:relative; 7 | cursor:e-resize; 8 | } 9 | .range-slider-track:before { 10 | content:""; 11 | display:block; 12 | position:absolute; 13 | top:9px; 14 | left:0; 15 | width:100%; 16 | height:2px; 17 | background-color:black; 18 | } 19 | .range-slider-track .dragger { 20 | display:block; 21 | width:10px; 22 | height:inherit; 23 | position:relative; 24 | z-index:2; 25 | background-color:red; 26 | cursor:inherit; 27 | /* opacity:.6; */ 28 | } 29 | .range-slider-vertical { 30 | display:inline-block; 31 | vertical-align:middle; 32 | margin:5px 10px 5px 0; 33 | } 34 | .range-slider-vertical .range-slider-track { 35 | cursor:n-resize; 36 | width:20px; 37 | height:100px; 38 | } 39 | .range-slider-vertical .range-slider-track:before { 40 | top:0; 41 | right:auto; 42 | left:9px; 43 | width:2px; 44 | height:100%; 45 | } 46 | .range-slider-vertical .range-slider-track .dragger { 47 | width:inherit; 48 | height:10px; 49 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Taufik Nurrohman 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /range-slider.test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Range Slider 7 | 8 | 36 | 37 | 38 |

39 |

40 |

41 |

42 | 43 | 50 | 51 | -------------------------------------------------------------------------------- /range-slider.multiple-range.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Range Slider 7 | 8 | 24 | 25 | 26 | 27 |

28 |

From 0 to 0

29 | 30 | 45 | 46 | -------------------------------------------------------------------------------- /range-slider.custom.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Range Slider 7 | 8 | 13 | 14 | 15 |

16 |

17 |

18 |

19 | 20 | 47 | 48 | -------------------------------------------------------------------------------- /range-slider.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * ========================================================== 3 | * RANGE SLIDER 2.0.1 4 | * ========================================================== 5 | * Author: Taufik Nurrohman 6 | * License: MIT 7 | * ---------------------------------------------------------- 8 | */ 9 | function RS(e,t,n){function E(e){return"undefined"!=typeof e}function L(e){return"function"==typeof e}function y(e){for(var t=e[h];e=e.offsetParent;)t+=e[h];return t}function w(e,t,n){t.addEventListener?t.addEventListener(e,n,!1):t.attachEvent?t.attachEvent("on"+e,n):t["on"+e]=n}function x(e,t,n){t.removeEventListener?t.removeEventListener(e,n):t.detachEvent?t.detachEvent("on"+e,n):t["on"+e]=null}function z(e,t){t.classList?t.classList.add(e):t.className+=" "+e}function C(e,t,n){return t>e?t:e>n?n:e}function D(e){return e.preventDefault&&e.preventDefault(),!1}function T(){s=f[d],c=y(f),u=i[d]}function X(){l=C(E(t.value)?t.value:0,0,100),i.style[v]=l/100*s-u/2+"px",L(t.create)&&t.create(l,e),L(t.drag)&&t.drag(l,e)}function Y(n){return T(),a=!0,H(n),w("touchmove",o,b),w("mousemove",o,b),L(t.start)&&t.start(l,e,n),D(n)}function b(e){return H(e),D(e)}function k(n){return a=!1,x("touchmove",o,b),x("mousemove",o,b),L(t.stop)&&t.stop(l,e,n),D(n)}function H(n){n=n||r.event;var f=n.touches?n.touches[0][p]:n[p],d=C(f-c,0,s),h=C((f-c)/s*100,0,100);f||(f=n[m]+o.body[g]+o.documentElement[g]),a&&(i.style[v]=d-u/2+"px",l=Math.round(h),L(t.drag)&&t.drag(l,e,n))}t=t||{};var r=window,o=document,f=o.createElement("div"),i=o.createElement("span"),a=!1,s=0,u=0,c=0,l=0,n=n||t.vertical||!1,d=n?"offsetHeight":"offsetWidth",v=n?"top":"left",p=n?"pageY":"pageX",h=n?"offsetTop":"offsetLeft",m=n?"clientY":"clientX",g=n?"scrollTop":"scrollLeft";return z("range-slider",e),z("range-slider-"+(n?"vertical":"horizontal"),e),z("range-slider-track",f),z("dragger",i),L(t)&&(t={drag:t}),w("touchstart",f,Y),w("mousedown",f,Y),w("touchend",o,k),w("mouseup",o,k),w("resize",r,function(e){T(),a=!1,i.style[v]=l/100*s-u/2+"px"}),f.appendChild(i),e.appendChild(f),T(),X(),e} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Simple Custom Range Slider 2 | ========================== 3 | 4 | > The simplest JavaScript custom range slider ever! 5 | 6 | [![View Demo](https://cloud.githubusercontent.com/assets/1669261/17064930/5fd9e440-5069-11e6-9f61-071b0be5bd56.png)](https://taufik-nurrohman.github.io/range-slider/range-slider.html "View Demo") 7 | 8 | Basic Usage 9 | ----------- 10 | 11 | The required HTML is: 12 | 13 | ~~~ .html 14 |
15 | ~~~ 16 | 17 | Execution… 18 | 19 | ### Basic 20 | 21 | ~~~ .js 22 | // horizontal slider 23 | RS(document.getElementById('range-slider-1'), function(value, target, event) { 24 | console.log(value); 25 | }); 26 | 27 | // vertical slider 28 | RS(document.getElementById('range-slider-1'), function(value, target, event) { 29 | console.log(value); 30 | }, true); 31 | ~~~ 32 | 33 | ### Advance 34 | 35 | ~~~ .js 36 | RS(document.getElementById('range-slider-1'), { 37 | value: 1, // initial value 38 | vertical: false, // vertical or horizontal slider? 39 | create: function(value, target) { … }, // create event 40 | start: function(value, target, event) { … }, // start event 41 | drag: function(value, target, event) { … }, // drag event 42 | stop: function(value, target, event) { … } // stop event 43 | }); 44 | ~~~ 45 | 46 | Examples 47 | -------- 48 | 49 | - [No Idea?](https://taufik-nurrohman.github.io/range-slider/range-slider.noob.html) 50 | - [Custom Classes](https://taufik-nurrohman.github.io/range-slider/range-slider.custom.html) 51 | - [Fallback to HTML5 `` if JavaScript is Disabled](https://taufik-nurrohman.github.io/range-slider/range-slider.replace.html) 52 | - [Custom `min` and `max` Value in Range Slider as Pixel](https://taufik-nurrohman.github.io/range-slider/range-slider.custom-range.html) 53 | - [Tooltip](https://taufik-nurrohman.github.io/range-slider/range-slider.tip.html) 54 | 55 | Folks 56 | ----- 57 | 58 | > **Update 2016/07/21:** Is now has support for touch devices by default. 59 | 60 | - Added support for touch devices by @beard86 → [link](https://github.com/beard86/simple-custom-range-slider) 61 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Range Slider 7 | 8 | 43 | 44 | 45 | 46 |

Like this project? Please support my Mecha CMS project too. Thank you!

47 | 48 |
49 | 0% 50 | 0% 51 |
52 | 53 |

Horizontal Slider

54 |
55 | 56 |

Vertical Slider

57 |
58 | 59 | 60 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /range-slider.tip.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Range Slider 7 | 8 | 54 | 55 | 56 |

57 |
58 |
59 |
60 |

61 | 62 | 96 | 97 | -------------------------------------------------------------------------------- /range-slider.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * ========================================================== 3 | * RANGE SLIDER 2.0.1 4 | * ========================================================== 5 | * Author: Taufik Nurrohman 6 | * License: MIT 7 | * ---------------------------------------------------------- 8 | */ 9 | 10 | function RS(target, event, vertical) { 11 | 12 | event = event || {}; 13 | 14 | var win = window, 15 | doc = document, 16 | ranger = doc.createElement('div'), 17 | dragger = doc.createElement('span'), 18 | drag = false, 19 | rangerSize = 0, 20 | draggerSize = 0, 21 | rangerDistance = 0, 22 | cacheValue = 0, 23 | vertical = vertical || event.vertical || false, 24 | size = vertical ? 'offsetHeight' : 'offsetWidth', 25 | css = vertical ? 'top' : 'left', 26 | page = vertical ? 'pageY' : 'pageX', 27 | offset = vertical ? 'offsetTop' : 'offsetLeft', 28 | client = vertical ? 'clientY' : 'clientX', 29 | scroll = vertical ? 'scrollTop' : 'scrollLeft'; 30 | 31 | function isSet(x) { 32 | return typeof x !== "undefined"; 33 | } 34 | 35 | function isFunc(x) { 36 | return typeof x === "function"; 37 | } 38 | 39 | function getCoordinate(el) { 40 | var x = el[offset]; 41 | while (el = el.offsetParent) { 42 | x += el[offset]; 43 | } 44 | return x; 45 | } 46 | 47 | function on(ev, el, fn) { 48 | if (el.addEventListener) { 49 | el.addEventListener(ev, fn, false); 50 | } else if (el.attachEvent) { 51 | el.attachEvent('on' + ev, fn); 52 | } else { 53 | el['on' + ev] = fn; 54 | } 55 | } 56 | 57 | function off(ev, el, fn) { 58 | if (el.removeEventListener) { 59 | el.removeEventListener(ev, fn); 60 | } else if (el.detachEvent) { 61 | el.detachEvent('on' + ev, fn); 62 | } else { 63 | el['on' + ev] = null; 64 | } 65 | } 66 | 67 | function addClass(s, el) { 68 | if (el.classList) { 69 | el.classList.add(s); 70 | } else { 71 | el.className += ' ' + s; 72 | } 73 | } 74 | 75 | addClass('range-slider', target); 76 | addClass('range-slider-' + (vertical ? 'vertical' : 'horizontal'), target); 77 | addClass('range-slider-track', ranger); 78 | addClass('dragger', dragger); 79 | 80 | // `RS(target, function(a, b, c) {})` 81 | if (isFunc(event)) { 82 | event = { 83 | drag: event 84 | }; 85 | } 86 | 87 | function edge(a, b, c) { 88 | if (a < b) return b; 89 | if (a > c) return c; 90 | return a; 91 | } 92 | 93 | function preventDefault(e) { 94 | if (e.preventDefault) e.preventDefault(); 95 | return false; 96 | } 97 | 98 | function setSize() { 99 | rangerSize = ranger[size]; 100 | rangerDistance = getCoordinate(ranger); 101 | draggerSize = dragger[size]; 102 | } 103 | 104 | function dragInit() { 105 | cacheValue = edge(isSet(event.value) ? event.value : 0, 0, 100); 106 | dragger.style[css] = (((cacheValue / 100) * rangerSize) - (draggerSize / 2)) + 'px'; 107 | if (isFunc(event.create)) event.create(cacheValue, target); 108 | if (isFunc(event.drag)) event.drag(cacheValue, target); 109 | } 110 | 111 | function dragStart(e) { 112 | setSize(), drag = true, dragUpdate(e); 113 | on("touchmove", doc, dragMove); 114 | on("mousemove", doc, dragMove); 115 | if (isFunc(event.start)) event.start(cacheValue, target, e); 116 | return preventDefault(e); 117 | } 118 | 119 | function dragMove(e) { 120 | dragUpdate(e); 121 | return preventDefault(e); 122 | } 123 | 124 | function dragStop(e) { 125 | drag = false; 126 | off("touchmove", doc, dragMove); 127 | off("mousemove", doc, dragMove); 128 | if (isFunc(event.stop)) event.stop(cacheValue, target, e); 129 | return preventDefault(e); 130 | } 131 | 132 | function dragUpdate(e) { 133 | e = e || win.event; 134 | var pos = e.touches ? e.touches[0][page] : e[page], 135 | move = edge(pos - rangerDistance, 0, rangerSize), 136 | value = edge(((pos - rangerDistance) / rangerSize) * 100, 0, 100); 137 | if (!pos) pos = e[client] + doc.body[scroll] + doc.documentElement[scroll]; 138 | if (drag) { 139 | dragger.style[css] = (move - (draggerSize / 2)) + 'px'; 140 | cacheValue = Math.round(value); 141 | if (isFunc(event.drag)) event.drag(cacheValue, target, e); 142 | } 143 | } 144 | 145 | on("touchstart", ranger, dragStart); 146 | on("mousedown", ranger, dragStart); 147 | 148 | on("touchend", doc, dragStop); 149 | on("mouseup", doc, dragStop); 150 | 151 | on("resize", win, function(e) { 152 | setSize(), drag = false; 153 | dragger.style[css] = (((cacheValue / 100) * rangerSize) - (draggerSize / 2)) + 'px'; 154 | }); 155 | 156 | ranger.appendChild(dragger); 157 | target.appendChild(ranger); 158 | 159 | return setSize(), dragInit(), target; 160 | 161 | } --------------------------------------------------------------------------------