├── .babelrc ├── .eslintrc.js ├── .gitignore ├── .travis.yml ├── History.md ├── LICENSE.md ├── README.md ├── config ├── .eslintrc ├── dev.env.js ├── index.js ├── prod.env.js └── test.env.js ├── dev.html ├── dist ├── index.html ├── rangeslider-js.min.js └── styles.min.css ├── docs ├── .nojekyll ├── api.md ├── config.js ├── examples.md ├── index.html └── landing.html ├── package-lock.json ├── package.json ├── prod.html ├── src ├── const.js ├── dev.js ├── index.js ├── rangeslider.js ├── styles.css └── utils.js ├── test ├── helpers │ └── ava-setup.js └── unit │ ├── const.js │ ├── index.js │ └── utils.js └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/preset-env", { 4 | // "modules": false, 5 | "targets": { 6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 10"] 7 | } 8 | }] 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parserOptions: { 4 | sourceType: 'module' 5 | }, 6 | env: { 7 | browser: true, 8 | }, 9 | extends: 'standard', 10 | globals: { 11 | 'rangesliderJs': false, 12 | 'PROD': false, 13 | 'DEV': false, 14 | 'TEST': false, 15 | 'docute': false, 16 | 'docuteIframe': false 17 | }, 18 | rules: { 19 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, 20 | 'no-console': process.env.NODE_ENV === 'production' ? 2 : 0, 21 | 'semi': 2, 22 | 'no-alert': 2, 23 | 'prefer-const': 2, 24 | 'no-var': 2 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Sublime Text files 2 | *.sublime* 3 | *.*~*.TMP 4 | 5 | # OS temp files 6 | .DS_Store 7 | Thumbs.db 8 | Desktop.ini 9 | 10 | # Tool temp files 11 | npm-debug.log 12 | *.sw* 13 | \#*# 14 | 15 | # project ignores 16 | !.gitkeep 17 | node_modules 18 | 19 | .idea/ 20 | disc.html 21 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - '10' 5 | -------------------------------------------------------------------------------- /History.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ###Release 3.2.5 4 | >*May 20, 2019* 5 | 6 | * fixes examples in docs [9c54791](https://github.com/stbaer/rangeslider-js/commits/9c54791732a45eebfc3c5a3bd11c5506a0c9e482) 7 | 8 | 9 | 10 | ###Release 3.2.4 11 | >*May 20, 2019* 12 | 13 | * fixes ava tests (babel setup) [733e9cd](https://github.com/stbaer/rangeslider-js/commits/733e9cd73209d865b9d30bdc2b1d67b3633a2e0e) 14 | * fixes travis.yml - node version should be a string [03b5304](https://github.com/stbaer/rangeslider-js/commits/03b53045cdf8cb22ac1e1ecd919d1fd24522b3f1) 15 | 16 | 17 | 18 | ###Release 3.2.3 19 | >*May 18, 2019* 20 | 21 | * added libraryExport: 'default' to webpack config [2d312cd](https://github.com/stbaer/rangeslider-js/commits/2d312cd7935d492938776e92e4cb0abeb619d94e) 22 | 23 | 24 | 25 | ###Release 3.2.2 26 | >*May 17, 2019* 27 | 28 | * updates dependencies; fixes export; [4b918d0](https://github.com/stbaer/rangeslider-js/commits/4b918d0bfefb80f52a88d35c69d52dc5f5a29d7d) 29 | * updated travis.yml, added engines to package.json; [98b26e1](https://github.com/stbaer/rangeslider-js/commits/98b26e157b04fa6f38934e69420af1737cd55e8a) 30 | 31 | 32 | 33 | ###Release 3.2.1 34 | >*November 26, 2018* 35 | 36 | * updated docs index.html [d8c53bd](https://github.com/stbaer/rangeslider-js/commits/d8c53bd3196f9787e77b314e7646bfcea1006cc1) 37 | 38 | 39 | 40 | ###Release 3.2.0 41 | >*November 26, 2018* 42 | 43 | * cssnano -> csso [5bcc288](https://github.com/stbaer/rangeslider-js/commits/5bcc2889111d5beb000a0a530554ac0cfe22df92) 44 | * updated sources for docs, fixes issue #5 [f293e99](https://github.com/stbaer/rangeslider-js/commits/f293e998c76cd501219579cbb5dac99d76ee6fae) 45 | * Merge branch 'develop' of github.com:stbaer/rangeslider-js into develop [50fed44](https://github.com/stbaer/rangeslider-js/commits/50fed4405f4bc9d2cd62186b11922f7381669238) 46 | * updated all dependencies and babel config [e798d3b](https://github.com/stbaer/rangeslider-js/commits/e798d3bcac9b7dea2ee01a9449d4d2a783228610) 47 | * lint fixes [837a17a](https://github.com/stbaer/rangeslider-js/commits/837a17a475ccbca1cf2119fe91d752605ef411bf) 48 | * updated dependencies [c124933](https://github.com/stbaer/rangeslider-js/commits/c124933ca16cbfff003e2628405441dd69a75a8b) 49 | * [f4b8808](https://github.com/stbaer/rangeslider-js/commits/f4b880834b2f1c51a085b26e34c339bef5b8e614) 50 | * [28b6ca4](https://github.com/stbaer/rangeslider-js/commits/28b6ca490a8c4f0d30f76281cd0765104ef06a97) 51 | 52 | 53 | 54 | ###Release 3.1.2 55 | >*April 26, 2018* 56 | 57 | * build / dev conf [012db12](https://github.com/stbaer/rangeslider-js/commits/012db12338ef8ffb5235064475de06cb025bc041) 58 | * updated dependencies [bbc090b](https://github.com/stbaer/rangeslider-js/commits/bbc090b0c56e4efe42751a87f20ce9258706d964) 59 | * added files field to package.json; removed .eslintignore; [99bb1be](https://github.com/stbaer/rangeslider-js/commits/99bb1be14b71ba741d7226c65fcaa31e0dd4a647) 60 | * removed pre-commit and pre-push hooks, removed dependency [a6c82ef](https://github.com/stbaer/rangeslider-js/commits/a6c82ef1351e9207aee0af627e08e3187ccbf907) 61 | * webpack updated to 4 and updated other deps [780efd1](https://github.com/stbaer/rangeslider-js/commits/780efd1135dfaefb8520b73ec278b033f8316cb1) 62 | 63 | 64 | 65 | ###Release 3.1.1 66 | >*October 29, 2017* 67 | 68 | * added package-lock to release config version files [4f4b323](https://github.com/stbaer/rangeslider-js/commits/4f4b323279a5e1f6ecd94a2722cd63e0bd3ed8e4) 69 | * updated dependencies [cb740e1](https://github.com/stbaer/rangeslider-js/commits/cb740e1203d428db04f9093300eeacdfcd759199) 70 | 71 | 72 | 73 | ###Release 3.1.0 74 | >*July 9, 2017* 75 | 76 | * updated docs, added analyze npm script; [529ef82](https://github.com/stbaer/rangeslider-js/commits/529ef82ce62d352aa432254cf5e87497f3014fdd) 77 | * added package-lock [0b8a6e0](https://github.com/stbaer/rangeslider-js/commits/0b8a6e001d4a504392053f7d18ac68b9b1f78884) 78 | * updated deps and dev files [d64a276](https://github.com/stbaer/rangeslider-js/commits/d64a276d64bd83411817b071b1db7d414c72e645) 79 | * updated Licence year [60cd690](https://github.com/stbaer/rangeslider-js/commits/60cd6904bd25944ba762b149bed3dcc2bf34aabb) 80 | * updated tests [2b0f922](https://github.com/stbaer/rangeslider-js/commits/2b0f92285d969c4b452adc0292aa0eb1c7a7a7f5) 81 | * feat: update function accepts strings instead of numbers for convenience [e5595c4](https://github.com/stbaer/rangeslider-js/commits/e5595c4daccc7507587ce752baf11389f6c8af54) 82 | * dependency updates [61c6c1c](https://github.com/stbaer/rangeslider-js/commits/61c6c1c65d83c761175695d9b348b898732facbf) 83 | * docs [3183afe](https://github.com/stbaer/rangeslider-js/commits/3183afe4cf7eda29c915797c5c6190d4186a02fd) 84 | 85 | 86 | 87 | ###Release 3.0.2 88 | >*May 9, 2017* 89 | 90 | * removed module from package.json for now [860338a](https://github.com/stbaer/rangeslider-js/commits/860338abb1fcfc8b04e93cea9016ace2ea5d0e71) 91 | 92 | 93 | 94 | ###Release 3.0.1 95 | >*May 9, 2017* 96 | 97 | * added gf-release dev dep and history.md [18f9fba](https://github.com/stbaer/rangeslider-js/commits/18f9fba6079416a5fa46b7107883173dd708a2b8) 98 | * added gf-release dev dep and history.md [9eff86a](https://github.com/stbaer/rangeslider-js/commits/9eff86a109bd6a54a4fcb08111bc8b7f8b501d26) 99 | * added libraryTarget to webpack config; package updates; [1f98884](https://github.com/stbaer/rangeslider-js/commits/1f9888439070cbd03a83d511c7bfcddec49cb5ab) 100 | * inch-ci and dependency status badges added to readme [e595532](https://github.com/stbaer/rangeslider-js/commits/e595532af77e920e2a33dc51246b5a5211e24f28) 101 | 102 | 103 | 104 | ###Release 3.0.0 105 | >*May 7, 2017* 106 | 107 | * added travis build status to the readme [9cb662a](https://github.com/stbaer/rangeslider-js/commits/9cb662a3db89014f707f1d1ea8231da023a3c24e) 108 | * added travis yaml and more tests [b3b9a8d](https://github.com/stbaer/rangeslider-js/commits/b3b9a8dbe0ca27d885119adcee8bdade5c166050) 109 | 110 | ###Release 3.0.0-beta.4 111 | >*May 7, 2017* 112 | 113 | 114 | ###Release 3.0.0-beta.3 115 | >*May 7, 2017* 116 | 117 | * fix: init multiple; updated docs; [f651c37](https://github.com/stbaer/rangeslider-js/commits/f651c37034fe731bbfa2becb885b1873c2f4130f) 118 | 119 | ###Release 3.0.0-beta.2 120 | >*May 6, 2017* 121 | 122 | * updated docs link [947bf0c](https://github.com/stbaer/rangeslider-js/commits/947bf0cb3fae611fa94d04c173ffb34540378730) 123 | 124 | ###Release 3.0.0-beta.1 125 | >*May 6, 2017* 126 | 127 | * minor [154c9d4](https://github.com/stbaer/rangeslider-js/commits/154c9d4e7b4e641c585d2c6535ad3449a6cbd1df) 128 | * minor jsdoc and readme updates [a2e7a9f](https://github.com/stbaer/rangeslider-js/commits/a2e7a9fb65a95ae13c4baa073a763fb319f066f9) 129 | * updated docs, more tests, split up code [f672c04](https://github.com/stbaer/rangeslider-js/commits/f672c04af59eccf46d10143889b3f7f7424d7560) 130 | * updated docs [e2136a4](https://github.com/stbaer/rangeslider-js/commits/e2136a4190dc61e4c2974911f6cc94dc98a92087) 131 | * more es6, webpack config, cleaned up old files [01bf8d4](https://github.com/stbaer/rangeslider-js/commits/01bf8d4aa6cf8c6991cbdf8afc051d0d7b533b37) 132 | * added pre-commit and pre-push hooks [9c92b74](https://github.com/stbaer/rangeslider-js/commits/9c92b740dcd5882fcec7b043771b9f1881bba145) 133 | * wip [9444868](https://github.com/stbaer/rangeslider-js/commits/9444868b497867210ffa86f37fede74546b288bc) 134 | * updated debounce [bb6c76e](https://github.com/stbaer/rangeslider-js/commits/bb6c76ee7cd1f021e18bd8b8ac8264432c705f0f) 135 | * .. [adeb5e0](https://github.com/stbaer/rangeslider-js/commits/adeb5e0e4382237c00cb0566a3f2eb9cd48455d0) 136 | * added webpack config; switched to eslint; don't include css in the js build anymore; [8994f84](https://github.com/stbaer/rangeslider-js/commits/8994f84149f7326739813af304372fa863e62723) 137 | 138 | ###Release 2.1.2 139 | >*February 11, 2017* 140 | 141 | * added beefy to dev deps [ea21444](https://github.com/stbaer/rangeslider-js/commits/ea214447cdb21de92cd2c7b9036af3d85f44d995) 142 | * minor cleanup; fix hint error; [528a5db](https://github.com/stbaer/rangeslider-js/commits/528a5db6b9bb6004b442d6f2313427e23618f203) 143 | * removed clamp package; moved cssify to dev deps; [2433e4f](https://github.com/stbaer/rangeslider-js/commits/2433e4f80bb7e8386cd575a93b53a9ac00e49dc1) 144 | * bump browserify [44ac352](https://github.com/stbaer/rangeslider-js/commits/44ac352360fa9e710d658e978bd1ea9181a5c45f) 145 | 146 | ###Release 2.1.1 147 | >*December 15, 2016* 148 | 149 | * updated deps [a1be557](https://github.com/stbaer/rangeslider-js/commits/a1be557afc3d4f619e8abc9f9912cdb166c49083) 150 | 151 | ###Release 2.1.0 152 | >*May 14, 2016* 153 | 154 | * updated dev deps [0a21f6a](https://github.com/stbaer/rangeslider-js/commits/0a21f6a17b12afda129931f6be5f41c0c9d14597) 155 | * updated readme [3e49a2f](https://github.com/stbaer/rangeslider-js/commits/3e49a2f82d4dda5ae8ccbc6803694daa77e9e462) 156 | * minor fix; build [f33d6c1](https://github.com/stbaer/rangeslider-js/commits/f33d6c12fdf102aa422ebb91e295f09c47a9ed6c) 157 | * removed es6/babelify again; switched from lessify to cssify [8d6a47a](https://github.com/stbaer/rangeslider-js/commits/8d6a47a3403d3217864904897dc5b76ec06351e0) 158 | 159 | ###Release 2.0.3 160 | >*April 9, 2016* 161 | 162 | * fix set attributes [fadd16a](https://github.com/stbaer/rangeslider-js/commits/fadd16a5292990d170472daf11a805abcae77d46) 163 | * build [32985cd](https://github.com/stbaer/rangeslider-js/commits/32985cd49594febc3cf9a783ad4d7e775a9c15d3) 164 | * some cleanup [c84e98b](https://github.com/stbaer/rangeslider-js/commits/c84e98b7208b733976ad3280254d7f39b928225e) 165 | 166 | ###Release 2.0.2 167 | >*March 13, 2016* 168 | 169 | * changed babel ignore to only [bfe5663](https://github.com/stbaer/rangeslider-js/commits/bfe56632269c6ece3004bb50186ee09240aa7dbf) 170 | 171 | ###Release 2.0.1 172 | >*March 13, 2016* 173 | 174 | * cleaned up unused babel plugins [175e6da](https://github.com/stbaer/rangeslider-js/commits/175e6daa5065898f378f25841d7d6b7ee5c31238) 175 | 176 | ###Release 2.0.0 177 | >*March 13, 2016* 178 | 179 | * es6 setup, removed gulp, use lessify to inline styles, updated npm scripts [6052eeb](https://github.com/stbaer/rangeslider-js/commits/6052eeb4dc51cccf61908e0a4c88c6560c8a4738) 180 | 181 | ###Release 1.2.10 182 | >*December 25, 2015* 183 | 184 | * updated deps; build [d2dc861](https://github.com/stbaer/rangeslider-js/commits/d2dc8613d798cfa6275bb61d3d460680f90d7113) 185 | * updated .gitignore and package.json [59e73db](https://github.com/stbaer/rangeslider-js/commits/59e73db792c8ea28923fae7070a19d955c9cb5fd) 186 | 187 | ###Release 1.2.9 188 | >*September 26, 2015* 189 | 190 | * minor cleanup [1f989fd](https://github.com/stbaer/rangeslider-js/commits/1f989fdcda10492ec44cabc7a997c3806b0df5e2) 191 | * prefer dependencies - use is-finite pkg [5f5bbfa](https://github.com/stbaer/rangeslider-js/commits/5f5bbfaa2428ff38f63a166af655a97e5c81596e) 192 | * prefer dependencies - use custom-event pkg [ca285f3](https://github.com/stbaer/rangeslider-js/commits/ca285f3990b97ef4146f7ddaef051a5a4b9b96e5) 193 | 194 | ###Release 1.2.8 195 | >*September 26, 2015* 196 | 197 | * replaced lodash [cd55bb6](https://github.com/stbaer/rangeslider-js/commits/cd55bb6df7cbeb57bce3fbc8b165950c6d6c3845) 198 | * cleaned up deps and gulp tasks [9431685](https://github.com/stbaer/rangeslider-js/commits/94316859eaf1d15710a138cf7475a2dc4cefd446) 199 | 200 | ###Release 1.2.7 201 | >*September 25, 2015* 202 | 203 | * updated browserify [c235326](https://github.com/stbaer/rangeslider-js/commits/c235326154f554e913dbae4ccf8b2c00811380f3) 204 | * removed and replaced some deps [1c3e787](https://github.com/stbaer/rangeslider-js/commits/1c3e7876f08036482b5c0299c83f6ba9cc97934d) 205 | 206 | ###Release 1.2.6 207 | >*September 11, 2015* 208 | 209 | * updated deps; fixed clean task [fc08d37](https://github.com/stbaer/rangeslider-js/commits/fc08d3767623a1a5cc2c9e9ad5674f686f9426ba) 210 | 211 | ###Release 1.2.6-3 212 | >*August 24, 2015* 213 | 214 | * fixes set step by attribute [d96ff09](https://github.com/stbaer/rangeslider-js/commits/d96ff0988ab9a704c4418b9ed499664d7654291f) 215 | 216 | ###Release 1.2.6-2 217 | >*August 24, 2015* 218 | 219 | * updated readme and dev deps [779f656](https://github.com/stbaer/rangeslider-js/commits/779f65611dd2309c08cb71d1ff380877b3744787) 220 | 221 | ###Release 1.2.6-1 222 | >*August 15, 2015* 223 | 224 | * fixed undefined error in update method [83621b0](https://github.com/stbaer/rangeslider-js/commits/83621b0997623859a52655d0fd1b1c89970cbb39) 225 | 226 | ###Release 1.2.6-0 227 | >*August 15, 2015* 228 | 229 | * utils fix [fe08ed6](https://github.com/stbaer/rangeslider-js/commits/fe08ed68f9d905723b6f63affd67cbbde77ef130) 230 | 231 | ###Release 1.2.5 232 | >*August 15, 2015* 233 | 234 | * use transform for changing the handle pos; moved some things to const and utils; updated slim styles [76ea203](https://github.com/stbaer/rangeslider-js/commits/76ea203b7fbdd9489e2332b4016cdebff78454f2) 235 | * made getRelativePosition an external module; replaced getPositionFromNode with getBoundingClientRect [3c8e98b](https://github.com/stbaer/rangeslider-js/commits/3c8e98b87a0c14d655bfbd4a61d8290f25147834) 236 | 237 | ###Release 1.2.4 238 | >*August 14, 2015* 239 | 240 | * build; added untracked files from last commit [54bee25](https://github.com/stbaer/rangeslider-js/commits/54bee257f377ed4de4b0f2054c75ce9bd4bbabb4) 241 | * touch fix; added minimal visual test [1e9f3f3](https://github.com/stbaer/rangeslider-js/commits/1e9f3f3a8e1f2d7605c8f4393b05051c628c89a6) 242 | * Readme fix [cfd12b8](https://github.com/stbaer/rangeslider-js/commits/cfd12b8c61bd1b6a64e95e0120494f6c050efbfd) 243 | * updated deps; check if e.originalEvent exists (chrome bug) [aa49dcb](https://github.com/stbaer/rangeslider-js/commits/aa49dcbb8e8aefbb4627abfb4e640bff14b392f9) 244 | * updated gulp-size [b80b87d](https://github.com/stbaer/rangeslider-js/commits/b80b87d1b70932eeb654828f2861ea6f01971e17) 245 | * updated lodash and browser-sync; build [0b4a198](https://github.com/stbaer/rangeslider-js/commits/0b4a198213c2aa808a0d1e7b9e291e86a053ee3b) 246 | 247 | ###Release 1.2.3 248 | >*July 31, 2015* 249 | 250 | * updated deps; fix hidden check; build [2ec2240](https://github.com/stbaer/rangeslider-js/commits/2ec2240d05c0e3e5b2a9b91c91cc4ea421e97731) 251 | * fixed typo in index.js; updated dependencies; removed unused gulp task; run example npm script [5fda5d4](https://github.com/stbaer/rangeslider-js/commits/5fda5d4ef60a2e3be83537029722ff607ea1a4a5) 252 | * updated dev dependencies [946b074](https://github.com/stbaer/rangeslider-js/commits/946b074e930e51ef57ca3fda76b54865fbc3b951) 253 | * minor change to index.js [3ab8f41](https://github.com/stbaer/rangeslider-js/commits/3ab8f4175714b5c29ed4aa54eeee3a562c8af674) 254 | * bump to 1.2.2 [3ad7b58](https://github.com/stbaer/rangeslider-js/commits/3ad7b58b5eb42a7af9bab50bef7624f8af50f3bd) 255 | 256 | ###Release 1.2.2 257 | >*July 10, 2015* 258 | 259 | * bump to 1.2.2 [3ad7b58](https://github.com/stbaer/rangeslider-js/commits/3ad7b58b5eb42a7af9bab50bef7624f8af50f3bd) 260 | * new build [d8e892e](https://github.com/stbaer/rangeslider-js/commits/d8e892e03c9ee3ede4b3cedbf5e39b0f9f1ce8e7) 261 | * changed _setValue func [1aea45d](https://github.com/stbaer/rangeslider-js/commits/1aea45d380ef03c874268e49d40f91b1429efd3f) 262 | * updated dependencies and .jshintrc; new build; [d6413ee](https://github.com/stbaer/rangeslider-js/commits/d6413eeb0915800c87d08dafaa6a7fba24de415f) 263 | 264 | ###Release 1.2.1-1 265 | >*July 1, 2015* 266 | 267 | * updated deps and examples; more [726fc46](https://github.com/stbaer/rangeslider-js/commits/726fc462f5c0406d9fef584c7bf3ef8cf903f0fe) 268 | 269 | ###Release 1.2.1-0 270 | >*June 24, 2015* 271 | 272 | * updated dependencies and Readme [ac7e24b](https://github.com/stbaer/rangeslider-js/commits/ac7e24b70addd6fb86b950341a738dd0ed264c7a) 273 | * version bump [7f92124](https://github.com/stbaer/rangeslider-js/commits/7f921244465ed524fb0197d7669a4c92afffc093) 274 | 275 | ###Release 1.2.0 276 | >*June 22, 2015* 277 | 278 | * version bump [7f92124](https://github.com/stbaer/rangeslider-js/commits/7f921244465ed524fb0197d7669a4c92afffc093) 279 | * fixed slider fill; updated some pkgs [5407f91](https://github.com/stbaer/rangeslider-js/commits/5407f91bad1ba11f4c95ba5c0b08c025490de550) 280 | * updated Readme [9f212a9](https://github.com/stbaer/rangeslider-js/commits/9f212a9b35ce222374eb5d662b82e213390ed780) 281 | * version bump [9524daa](https://github.com/stbaer/rangeslider-js/commits/9524daabe02ff9eb22ccbfcd2b9c91c45ec88ce3) 282 | 283 | ###Release 1.1.5 284 | >*June 21, 2015* 285 | 286 | * version bump [9524daa](https://github.com/stbaer/rangeslider-js/commits/9524daabe02ff9eb22ccbfcd2b9c91c45ec88ce3) 287 | * updated example [9033ce1](https://github.com/stbaer/rangeslider-js/commits/9033ce1f9201af07910c2f21b60df9ae70248882) 288 | * removed console.log [a1b9486](https://github.com/stbaer/rangeslider-js/commits/a1b94865c9a2076a7a4f2678e461a8372e8045a8) 289 | * fix for input event [f812c00](https://github.com/stbaer/rangeslider-js/commits/f812c00e4b3af86a0a0a69858ebd52f9ea3929a3) 290 | 291 | ###Release 1.1.4 292 | >*June 21, 2015* 293 | 294 | * fixed dependencies in package.json [4b3a936](https://github.com/stbaer/rangeslider-js/commits/4b3a93625bc34a9b0798c1be6526b892452a271e) 295 | 296 | ###Release 1.1.3 297 | >*June 21, 2015* 298 | 299 | * removed console.log [d2197c7](https://github.com/stbaer/rangeslider-js/commits/d2197c789b5f9025c570f41eb9bfcca21aa05358) 300 | * fixed callbacks for multiple sliders; added some browserify examples; updated deps; [90ac12b](https://github.com/stbaer/rangeslider-js/commits/90ac12b3bae7ebd8d965591d5e8a44adf0dfc2e1) 301 | * version bump [b35972f](https://github.com/stbaer/rangeslider-js/commits/b35972f363018dd15375e5157398cdcfaf77fb02) 302 | 303 | ###Release 1.1.2 304 | >*June 21, 2015* 305 | 306 | * version bump [b35972f](https://github.com/stbaer/rangeslider-js/commits/b35972f363018dd15375e5157398cdcfaf77fb02) 307 | * updated package.json [c3ada0a](https://github.com/stbaer/rangeslider-js/commits/c3ada0a868024b9f143f0e71b967110cf33ddb87) 308 | * updated Readme [6eb247e](https://github.com/stbaer/rangeslider-js/commits/6eb247ea6d15e68b6c703de8cfbf4d624aeb8616) 309 | * updated Readme [f5e3753](https://github.com/stbaer/rangeslider-js/commits/f5e3753d6ff865e87551fa5b5cb9ae938a9aac98) 310 | * updated Readme [6db27f9](https://github.com/stbaer/rangeslider-js/commits/6db27f9d99c7449349374b4119388b36a9cf0dde) 311 | * version bump [c73693d](https://github.com/stbaer/rangeslider-js/commits/c73693d044578cdf50713ade7c052f1d2c0ac9ed) 312 | 313 | ###Release 1.1.1 314 | >*June 21, 2015* 315 | 316 | * version bump [c73693d](https://github.com/stbaer/rangeslider-js/commits/c73693d044578cdf50713ade7c052f1d2c0ac9ed) 317 | * added disc npm script; updated .gitignore [19e0198](https://github.com/stbaer/rangeslider-js/commits/19e01982b9e582e31a6e61654d6ca8bd7fa28d03) 318 | 319 | ###Release 1.1.0-3 320 | >*June 20, 2015* 321 | 322 | * disabled sourcemaps for now [5e782fb](https://github.com/stbaer/rangeslider-js/commits/5e782fbc70fc0a136c26ca2edc41deaca7372e40) 323 | * fixed build task; updated dist [ab654e1](https://github.com/stbaer/rangeslider-js/commits/ab654e1713fcceac842f1553ac3d9e8d4109ad3a) 324 | * added testling badge [68a796f](https://github.com/stbaer/rangeslider-js/commits/68a796fe8e1454a293cdd26d56947051647fa67b) 325 | * added examples link to readme [f4424e1](https://github.com/stbaer/rangeslider-js/commits/f4424e199992742a3b2a75da59355b466e017174) 326 | * version bump [a93c926](https://github.com/stbaer/rangeslider-js/commits/a93c926eaf1e58f47ff4b86862dbbf384a098750) 327 | 328 | ###Release 1.1.0-2 329 | >*June 20, 2015* 330 | 331 | * version bump [a93c926](https://github.com/stbaer/rangeslider-js/commits/a93c926eaf1e58f47ff4b86862dbbf384a098750) 332 | * updated Readme [03f0530](https://github.com/stbaer/rangeslider-js/commits/03f053096e69511dbaeb5e873516747a54276cda) 333 | * version bump [d186e1c](https://github.com/stbaer/rangeslider-js/commits/d186e1c206cf24ca37295fe051c64898a68a0a0a) 334 | 335 | ###Release 1.1.0-0 336 | >*June 20, 2015* 337 | 338 | * version bump [d186e1c](https://github.com/stbaer/rangeslider-js/commits/d186e1c206cf24ca37295fe051c64898a68a0a0a) 339 | * changed package.json licence entry (ISC->MIT) [008fd39](https://github.com/stbaer/rangeslider-js/commits/008fd39e8ca17e682b19bc5828545cc9cb57e1ee) 340 | * use object-assign v2 for now [71b8ae2](https://github.com/stbaer/rangeslider-js/commits/71b8ae2666b9cc4fcc511b9fbf57fd44be968ea6) 341 | * removed dist from .gitignore; version bump [fe77d07](https://github.com/stbaer/rangeslider-js/commits/fe77d07204c33df54b4db0decd95465f3ae83283) 342 | 343 | ###Release 1.0.1 344 | >*June 20, 2015* 345 | 346 | * removed dist from .gitignore; version bump [fe77d07](https://github.com/stbaer/rangeslider-js/commits/fe77d07204c33df54b4db0decd95465f3ae83283) 347 | * moved object-assign to dev dependencies; updated jsdoc conf [7df9f88](https://github.com/stbaer/rangeslider-js/commits/7df9f88e1a0fad96add561073b25bb2203f8c134) 348 | * prefer dependencies, some cleanup, updated licence [67e2f22](https://github.com/stbaer/rangeslider-js/commits/67e2f22650c5a7b0844878faf71649a1dd277ac0) 349 | * some cleanup, simplified the contributing boilerplate [845792a](https://github.com/stbaer/rangeslider-js/commits/845792a76de93753cf28421995c91ba1bca97eab) 350 | * minor cleanup [6dd4a9a](https://github.com/stbaer/rangeslider-js/commits/6dd4a9a23baf543ec27a592f034ad9a4ed0d20d4) 351 | * updated styles and example [1384d89](https://github.com/stbaer/rangeslider-js/commits/1384d89328eec40ef64cd11a185b844ed41a15d3) 352 | * updated Readme [bab2004](https://github.com/stbaer/rangeslider-js/commits/bab20046804e5e306f36aaac1b752f0da48e4030) 353 | * added style build task; added examples; updated deps; more [bdd1eef](https://github.com/stbaer/rangeslider-js/commits/bdd1eef4f6f873b530d6f8ebe3ad092bf21bbb65) 354 | * renamed Plugin [dd90a09](https://github.com/stbaer/rangeslider-js/commits/dd90a09db196dbe21044402cacd0123fb7a5def2) 355 | * basic project structure/files and first working version [51ee943](https://github.com/stbaer/rangeslider-js/commits/51ee94310fd288be9b082f830c9b5ba8355e5bca) 356 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) Copyright (c) 2015-2018, Steffen Bär 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 4 | documentation files (the "Software"), to deal in the Software without restriction, including without limitation 5 | the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 6 | and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in all copies or substantial portions 9 | of the Software. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 12 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS 13 | OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 14 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rangeslider-js 2 | 3 | [![Build Status](https://travis-ci.org/stbaer/rangeslider-js.svg?branch=master)](https://travis-ci.org/stbaer/rangeslider-js) 4 | [![Inline docs](http://inch-ci.org/github/stbaer/rangeslider-js.svg?branch=master)](http://inch-ci.org/github/stbaer/rangeslider-js) 5 | [![Dependency Status](https://david-dm.org/stbaer/rangeslider-js.svg)](https://david-dm.org/stbaer/rangeslider-js) 6 | 7 | > Simple, fast and lightweight slider, touch friendly 8 | 9 | [Docs and Examples](http://stbaer.github.io/rangeslider-js/) 10 | 11 | - v1 was based on [rangeslider.js](https://github.com/andreruffert/rangeslider.js), main differences: 12 | - no jQuery 13 | - raf to throttle window resize, transform to set the handle position 14 | - fewer and only basic styles 15 | - no vertical mode 16 | 17 | ## Install 18 | 19 | `npm i rangeslider-js --save` 20 | 21 | ## Usage 22 | 23 | ```html 24 | 25 | 26 | 27 | ``` 28 | 29 | ```js 30 | import rangesliderJs from 'rangeslider-js' 31 | 32 | // single, options via js 33 | rangesliderJs.create(document.getElementById('slider1'), {min:0, max: 1, value: 0.5, step: 0.1}) 34 | 35 | // or single, options via html attributes 36 | rangesliderJs.create(document.getElementById('slider2')) 37 | 38 | // or initialize multiple 39 | rangesliderJs.create(document.querySelectorAll('input[type="range"]')) 40 | ``` 41 | 42 | ### Options 43 | 44 | ```js 45 | { 46 | min: 0, 47 | max: 100, 48 | value: 50, 49 | step: 1, 50 | // callbacks 51 | onInit: (value, percent, position) => {}, 52 | onSlideStart: (value, percent, position) => {}, 53 | onSlide: (value, percent, position) => {}, 54 | onSlideEnd: (value, percent, position) => {} 55 | } 56 | ``` 57 | 58 | ### Events 59 | 60 | 61 | 62 | ## Contribute or Report Issue 63 | 64 | Pull requests should target the **develop** branch. 65 | 66 | For bugs and feature requests, [please create an issue][10]. 67 | 68 | [10]: https://github.com/stbaer/rangeslider-js/issues 69 | 70 | ## Licence 71 | 72 | MIT, see [LICENSE.md](http://github.com/stbaer/rangeslider-js/blob/master/LICENSE.md) for details. 73 | -------------------------------------------------------------------------------- /config/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "node": true 4 | }, 5 | "rules": { 6 | "no-console": "off", 7 | "global-require": "off", 8 | "no-restricted-syntax": "off", 9 | "guard-for-in": "off", 10 | "import/no-extraneous-dependencies": "off" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /config/dev.env.js: -------------------------------------------------------------------------------- 1 | const merge = require('webpack-merge') 2 | const prodEnv = require('./prod.env') 3 | 4 | module.exports = merge(prodEnv, { 5 | NODE_ENV: '"development"' 6 | }) 7 | -------------------------------------------------------------------------------- /config/index.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | 3 | module.exports = { 4 | build: { 5 | env: require('./prod.env'), 6 | index: path.resolve(__dirname, '../dist/index.html'), 7 | assetsRoot: path.resolve(__dirname, '../dist'), 8 | assetsSubDirectory: '', 9 | assetsPublicPath: '/', 10 | productionSourceMap: false, 11 | bundleAnalyzerReport: process.env.npm_config_report 12 | }, 13 | dev: { 14 | env: require('./dev.env'), 15 | port: 8080, 16 | assetsSubDirectory: 'static', 17 | assetsPublicPath: '/', 18 | proxyTable: {}, 19 | cssSourceMap: true 20 | }, 21 | test: { 22 | env: require('./test.env'), 23 | productionSourceMap: true 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /config/prod.env.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | NODE_ENV: '"production"' 3 | } 4 | -------------------------------------------------------------------------------- /config/test.env.js: -------------------------------------------------------------------------------- 1 | const merge = require('webpack-merge') 2 | const devEnv = require('./dev.env') 3 | 4 | module.exports = merge(devEnv, { 5 | NODE_ENV: '"testing"' 6 | }) 7 | -------------------------------------------------------------------------------- /dev.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | rangeslider-js 7 | 35 | 36 | 37 |
38 |
39 |

Negative attributes

40 | 41 | 42 |
43 | 44 |
45 |

Floating point boundaries

46 | 47 |
48 | 49 | 50 |
51 |
52 | 53 | 54 |
55 |
56 | 57 | 58 |
59 |
60 | 61 |
62 |

value="0"

63 | 64 | 65 |
66 | 67 |
68 |

disabled

69 | 70 | 71 | 72 |
73 | 74 |
75 |

max="0" disables slider

76 | 77 | 78 |
79 | 80 |
81 |

Programmatic value changes

82 | 83 | 84 | 85 |
86 | 87 |
88 |

Update range

89 | 90 | 91 | 92 |
93 | 94 |
95 |

Destroy a plugin instance

96 | 97 | 98 | 99 | 100 |
101 | 102 |
103 |

Hide / show

104 | 105 |
106 | 107 | 108 |
109 | 110 |
111 |
112 | 113 | 114 | -------------------------------------------------------------------------------- /dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | rangeslider-js 7 | 8 | 9 | 10 | 11 |
12 |
13 | 14 |
15 |
16 | 17 |
18 |
19 |
20 | 21 |
22 |
23 |

24 |
25 | 26 | 27 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /dist/rangeslider-js.min.js: -------------------------------------------------------------------------------- 1 | !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.rangesliderJs=e():t.rangesliderJs=e()}(window,function(){return function(t){var e={};function n(i){if(e[i])return e[i].exports;var s=e[i]={i:i,l:!1,exports:{}};return t[i].call(s.exports,s,s.exports,n),s.l=!0,s.exports}return n.m=t,n.c=e,n.d=function(t,e,i){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var s in t)n.d(i,s,function(e){return t[e]}.bind(null,s));return i},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=3)}([function(t,e,n){"use strict";var i=function(t){return"number"==typeof t&&!isNaN(t)};t.exports=function(t,e){var n=(e=e||e.currentTarget).getBoundingClientRect(),s=t.originalEvent||t,r=0,o=0;return t.touches&&t.touches.length?i(t.touches[0].pageX)&&i(t.touches[0].pageY)?(r=t.touches[0].pageX,o=t.touches[0].pageY):i(t.touches[0].clientX)&&i(t.touches[0].clientY)&&(r=s.touches[0].clientX,o=s.touches[0].clientY):i(t.pageX)&&i(t.pageY)?(r=t.pageX,o=t.pageY):t.currentPoint&&i(t.currentPoint.x)&&i(t.currentPoint.y)&&(r=t.currentPoint.x,o=t.currentPoint.y),{x:r-n.left,y:o-n.top}}},function(t,e,n){(function(e){var n=e.CustomEvent;t.exports=function(){try{var t=new n("cat",{detail:{foo:"bar"}});return"cat"===t.type&&"bar"===t.detail.foo}catch(t){}return!1}()?n:"undefined"!=typeof document&&"function"==typeof document.createEvent?function(t,e){var n=document.createEvent("CustomEvent");return e?n.initCustomEvent(t,e.bubbles,e.cancelable,e.detail):n.initCustomEvent(t,!1,!1,void 0),n}:function(t,e){var n=document.createEventObject();return n.type=t,e?(n.bubbles=Boolean(e.bubbles),n.cancelable=Boolean(e.cancelable),n.detail=e.detail):(n.bubbles=!1,n.cancelable=!1,n.detail=void 0),n}}).call(this,n(2))},function(t,e){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(t){"object"==typeof window&&(n=window)}t.exports=n},function(t,e,n){"use strict";n.r(e);var i=n(1),s=n.n(i);function r(t){return 0===t.offsetWidth||0===t.offsetHeight||!1===t.open}window.requestAnimationFrame=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame;var o=Number.isNaN||function(t){return t!=t},a=Number.isFinite||function(t){return!("number"!=typeof t||o(t)||t===1/0||t===-1/0)};var u=function(){var t=[],e=!1;function n(){e||(e=!0,window.requestAnimationFrame?window.requestAnimationFrame(i):setTimeout(i,66))}function i(){t.forEach(function(t){t()}),e=!1}return{add:function(e){!t.length&&window.addEventListener("resize",n),function(e){e&&t.push(e)}(e)}}}(),l={emit:function(t,e,n){t.dispatchEvent(new s.a(e,n))},isFiniteNumber:a,getFirstNumberLike:function(){if(!arguments.length)return null;for(var t=0,e=arguments.length;tn?n:t:te?e:t},optimizedResize:u},h=n(0),c=n.n(h),d={MIN_DEFAULT:0,MAX_DEFAULT:100,RANGE_CLASS:"rangeslider",FILL_CLASS:"rangeslider__fill",FILL_BG_CLASS:"rangeslider__fill__bg",HANDLE_CLASS:"rangeslider__handle",DISABLED_CLASS:"rangeslider--disabled",STEP_DEFAULT:1,START_EVENTS:["mousedown","touchstart","pointerdown"],MOVE_EVENTS:["mousemove","touchmove","pointermove"],END_EVENTS:["mouseup","touchend","pointerup"],PLUGIN_NAME:"rangeslider-js"};function f(t,e){for(var n=0;n=i&&e A handle for the instance can always be retrieved via the DOM, e.g.: 28 | 29 | ```js 30 | const sliderInput = document.querySelector('.slider input[type="range"]') 31 | const sliderHandle = sliderInput['rangeslider-js'] 32 | 33 | sliderHandle.destroy() 34 | ``` 35 | 36 | ### update(values) 37 | 38 | Update the slider values. 39 | 40 | - values: 41 | - min (number|string) 42 | - max (number|string) 43 | - step (number|string) 44 | - value (number|string) 45 | ```js 46 | sliderHandle.update({ max: 50, value: '45' }) 47 | ``` 48 | 49 | ### destroy() 50 | 51 | Destroy the slider. 52 | ```js 53 | sliderHandle.destroy() 54 | ``` 55 | -------------------------------------------------------------------------------- /docs/config.js: -------------------------------------------------------------------------------- 1 | docute.init({ 2 | repo: 'stbaer/rangeslider-js', 3 | landing: true, 4 | debug: true, 5 | plugins: [ 6 | docuteIframe({ 7 | prepend: '' + 8 | '' + 9 | '' + 10 | '' 11 | }) 12 | ], 13 | nav: [ 14 | {title: 'Home', path: '/'}, 15 | {title: 'Docs', path: '/docs', source: 'https://raw.githubusercontent.com/stbaer/rangeslider-js/master/README.md'}, 16 | {title: 'Examples', path: '/examples'}, 17 | {title: 'API', path: '/api'}, 18 | {title: 'History', path: '/history', source: 'https://raw.githubusercontent.com/stbaer/rangeslider-js/master/History.md'} 19 | ] 20 | }) 21 | -------------------------------------------------------------------------------- /docs/examples.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | 4 | ## Options via html 5 | 6 | ````html 7 | 8 | 9 | 13 | ```` 14 | 15 | ## Options via js 16 | ````html 17 | 18 | 19 | 25 | ```` 26 | 27 | ## Initialize multiple 28 | 29 | ````html 30 | 31 | 32 | 33 | 34 | 35 | 39 | ```` 40 | 41 | ## Programmatic change 42 | 43 | ````html 44 | 45 | 46 | 47 | 57 | ```` 58 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | rangeslider-js 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /docs/landing.html: -------------------------------------------------------------------------------- 1 |
2 |

rangeslider-js

3 |

Simple, fast and lightweight slider

4 | 5 |
    6 |
  • Responsive
  • 7 |
  • Touch friendly
  • 8 |
  • lightweight, 3.x kb gzipped
  • 9 |
  • Pass init options via js or html attributes
  • 10 |
11 | 12 |

13 | Github 14 | Docs 15 |

16 |
17 | 18 | 69 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rangeslider-js", 3 | "version": "3.2.5", 4 | "main": "./dist/rangeslider-js.min.js", 5 | "description": "lightweight range slider", 6 | "author": "Steffen Bär ", 7 | "license": "MIT", 8 | "homepage": "https://github.com/stbaer/rangeslider-js", 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/stbaer/rangeslider-js.git" 12 | }, 13 | "bugs": { 14 | "url": "https://github.com/stbaer/rangeslider-js/issues" 15 | }, 16 | "keywords": [ 17 | "rangeslider", 18 | "plugin", 19 | "ui", 20 | "range", 21 | "slider" 22 | ], 23 | "scripts": { 24 | "prelint": "echo \"running eslint...\" && exit 0", 25 | "lint": "eslint -c ./.eslintrc.js --ext .js src config", 26 | "lintfix": "npm run lint -- --fix", 27 | "dev": "NODE_ENV=development webpack-dev-server --config webpack.config.js --env=development --progress --profile --colors --inline", 28 | "prebuild": "npm run lint && rm -rf ./dist", 29 | "build": "NODE_ENV=production webpack --config webpack.config.js --env=production --progress --profile --colors", 30 | "analyze": "npm run build --report", 31 | "postbuild": "csso src/styles.css > dist/styles.min.css", 32 | "pretest": "echo \"running tests...\" && exit 0", 33 | "test": "NODE_ENV=testing ava -v", 34 | "serve:docs": "docute ./docs", 35 | "release": "gf-release" 36 | }, 37 | "dependencies": { 38 | "custom-event": "^1.0.1", 39 | "ev-pos": "^1.0.1" 40 | }, 41 | "devDependencies": { 42 | "@babel/core": "7.4.4", 43 | "@babel/polyfill": "7.4.4", 44 | "@babel/preset-env": "7.4.4", 45 | "@babel/preset-stage-2": "7.0.0", 46 | "@babel/register": "7.4.4", 47 | "autoprefixer": "9.5.1", 48 | "ava": "1.4.1", 49 | "babel-eslint": "10.0.1", 50 | "babel-loader": "8.0.6", 51 | "babel-runtime": "6.26.0", 52 | "browser-env": "3.2.6", 53 | "css-loader": "2.1.1", 54 | "csso-cli": "2.0.2", 55 | "eslint": "5.16.0", 56 | "eslint-config-standard": "12.0.0", 57 | "eslint-friendly-formatter": "4.0.1", 58 | "eslint-loader": "2.1.2", 59 | "eslint-plugin-import": "2.17.2", 60 | "eslint-plugin-node": "9.0.1", 61 | "eslint-plugin-promise": "4.1.1", 62 | "eslint-plugin-standard": "4.0.0", 63 | "file-loader": "3.0.1", 64 | "friendly-errors-webpack-plugin": "1.7.0", 65 | "gf-release": "1.4.5", 66 | "html-webpack-plugin": "3.2.0", 67 | "mkdirp": "^0.5.1", 68 | "nodes-each": "1.0.3", 69 | "progress-bar-webpack-plugin": "1.12.1", 70 | "style-loader": "0.23.1", 71 | "url-loader": "1.1.2", 72 | "webpack": "4.31.0", 73 | "webpack-bundle-analyzer": "3.3.2", 74 | "webpack-cli": "3.3.2", 75 | "webpack-dev-server": "3.3.1", 76 | "webpack-merge": "4.2.1" 77 | }, 78 | "files": [ 79 | "dist/", 80 | "src/" 81 | ], 82 | "ava": { 83 | "concurrency": 5, 84 | "failFast": false, 85 | "require": [ 86 | "./test/helpers/ava-setup.js" 87 | ] 88 | }, 89 | "releaseConfig": { 90 | "buildCommand": "npm run build && git add -A && git commit -am \"updated build (--)\"; ", 91 | "versionFiles": [ 92 | "package.json", 93 | "package-lock.json" 94 | ], 95 | "commitMessagesExclude": [ 96 | "Merge tag", 97 | "Merge branch 'release", 98 | "Merge branch 'develop' into", 99 | "bumped", 100 | "bumbed", 101 | "(--)", 102 | "Merge branch 'feature/", 103 | "updated build", 104 | "bumped version" 105 | ], 106 | "commitBaseUrl": "https://github.com/stbaer/rangeslider-js/commits", 107 | "historyFile": "History.md" 108 | }, 109 | "engines": { 110 | "node": ">=10", 111 | "npm": ">=6" 112 | } 113 | } -------------------------------------------------------------------------------- /prod.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | rangeslider-js 7 | 8 | 9 | 10 | 11 |
12 |
13 | 14 |
15 |
16 | 17 |
18 |
19 |
20 | 21 |
22 |
23 |

24 |
25 | 26 | 27 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /src/const.js: -------------------------------------------------------------------------------- 1 | export default { 2 | MIN_DEFAULT: 0, 3 | MAX_DEFAULT: 100, 4 | RANGE_CLASS: 'rangeslider', 5 | FILL_CLASS: 'rangeslider__fill', 6 | FILL_BG_CLASS: 'rangeslider__fill__bg', 7 | HANDLE_CLASS: 'rangeslider__handle', 8 | DISABLED_CLASS: 'rangeslider--disabled', 9 | STEP_DEFAULT: 1, 10 | START_EVENTS: ['mousedown', 'touchstart', 'pointerdown'], 11 | MOVE_EVENTS: ['mousemove', 'touchmove', 'pointermove'], 12 | END_EVENTS: ['mouseup', 'touchend', 'pointerup'], 13 | PLUGIN_NAME: 'rangeslider-js' 14 | } 15 | -------------------------------------------------------------------------------- /src/dev.js: -------------------------------------------------------------------------------- 1 | import rangesliderJs from './index' 2 | import nodesEach from 'nodes-each' 3 | import './styles.css' 4 | 5 | const setOutput = element => (element.parentNode.getElementsByTagName('output')[0].innerHTML = element.value) 6 | const getTargetRange = btn => btn.parentNode.querySelector('input[type="range"]') 7 | 8 | console.log(rangesliderJs) 9 | 10 | function init () { 11 | const selector = '[data-rangeslider]' 12 | const elements = document.querySelectorAll(selector) 13 | 14 | // Example functionality to demonstrate a value feedback 15 | for (let i = elements.length - 1; i >= 0; i--) { 16 | setOutput(elements[i]) 17 | } 18 | 19 | nodesEach(document.querySelectorAll('input[type="range"]'), (i, rangeEl) => 20 | rangeEl.addEventListener('input', e => setOutput(e.target), false)) 21 | 22 | const toggleBtnDisable = document.querySelector('#js-example-disabled button[data-behaviour="toggle"]') 23 | toggleBtnDisable.addEventListener('click', e => { 24 | const inputRange = getTargetRange(toggleBtnDisable) 25 | inputRange.disabled = !inputRange.disabled 26 | inputRange['rangeslider-js'].update() 27 | }, false) 28 | 29 | // programmatic value changes 30 | const changeValBtn = document.querySelector('#programmatic input[type=number]') 31 | changeValBtn.addEventListener('input', e => { 32 | const inputRange = getTargetRange(changeValBtn) 33 | inputRange.value = e.target.value 34 | console.log(e.target.value) 35 | 36 | inputRange['rangeslider-js'].update({ value: e.target.value }) 37 | // inputRange.dispatchEvent(new Event('change')) 38 | }, false) 39 | 40 | // destroy 41 | const destroyBtn = document.querySelector('#js-example-destroy button[data-behaviour="destroy"]') 42 | destroyBtn.addEventListener('click', e => { 43 | const inputRange = getTargetRange(destroyBtn) 44 | inputRange['rangeslider-js'].destroy() 45 | }, false) 46 | 47 | const initBtn = document.querySelector('#js-example-destroy button[data-behaviour="initialize"]') 48 | initBtn.addEventListener('click', e => rangesliderJs.create(getTargetRange(initBtn), {}), false) 49 | 50 | // update range 51 | const updateBtn1 = document.querySelector('#js-example-update-range button') 52 | updateBtn1.addEventListener('click', e => getTargetRange(updateBtn1)['rangeslider-js'].update({ 53 | min: 0, 54 | max: 20, 55 | step: 0.5, 56 | value: 1.5 57 | }), false) 58 | 59 | const toggleBtn = document.querySelector('#js-example-hidden button[data-behaviour="toggle"]') 60 | toggleBtn.addEventListener('click', e => { 61 | const container = e.target.previousElementSibling 62 | container.style.display = container.style.display === 'none' ? '' : 'none' 63 | }, false) 64 | 65 | // Basic rangesliderJs initialization 66 | rangesliderJs.create(elements, { 67 | onInit: () => 68 | console.info('onSlideInit'), 69 | onSlideStart: (value, percent, position) => 70 | console.info('onSlideStart', 'value: ' + value, 'percent: ' + percent, 'position: ' + position), 71 | onSlide: (value, percent, position) => 72 | console.info('onSlide', 'value: ' + value, 'percent: ' + percent, 'position: ' + position), 73 | onSlideEnd: (value, percent, position) => 74 | console.info('onSlideEnd', 'value: ' + value, 'percent: ' + percent, 'position: ' + position) 75 | }) 76 | } 77 | 78 | window.onload = init() 79 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | /** @module rangesliderJs */ 2 | 3 | import utils from './utils' 4 | import RangeSlider from './rangeslider' 5 | import CONST from './const' 6 | 7 | /** 8 | * @type {object} 9 | */ 10 | export default { 11 | /** 12 | * @type {RangeSlider} 13 | */ 14 | RangeSlider, 15 | /** 16 | * Expose utils 17 | * @type {object} 18 | */ 19 | utils, 20 | /** 21 | * Plugin wrapper around the constructor, preventing multiple instantiations 22 | * 23 | * @param {Element|NodeList} el 24 | * @param {object} options 25 | */ 26 | create: (el, options) => { 27 | if (!el) return 28 | 29 | function createInstance (el) { 30 | el[CONST.PLUGIN_NAME] = el[CONST.PLUGIN_NAME] || new RangeSlider(el, options) 31 | } 32 | 33 | if (el.length) { 34 | Array.prototype.slice.call(el).forEach(el => createInstance(el)) 35 | } else { 36 | createInstance(el) 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/rangeslider.js: -------------------------------------------------------------------------------- 1 | /** @module rangesliderJs/Rangeslider */ 2 | 3 | import evPos from 'ev-pos' 4 | import utils from './utils' 5 | import CONST from './const' 6 | 7 | /** 8 | * @private 9 | * 10 | * @param {string} className 11 | * @returns {Element} 12 | */ 13 | const createChild = function (className) { 14 | const child = document && document.createElement('div') 15 | child.classList.add(className) 16 | return child 17 | } 18 | 19 | /** 20 | * @private 21 | * 22 | * @param step 23 | * @returns {number} 24 | */ 25 | const stepToFixed = step => (`${step}`.replace('.', '').length - 1) 26 | 27 | /** RangeSlider */ 28 | class RangeSlider { 29 | /** 30 | * @private 31 | * @constructor 32 | * @param {Element} el 33 | * @param {object} options 34 | * @property {number} [options.min] 35 | * @property {number} [options.max] 36 | * @property {number} [options.value] 37 | * @property {number} [options.step] 38 | * @property {function} [options.onInit] - init callback 39 | * @property {function} [options.onSlideStart] - slide start callback 40 | * @property {function} [options.onSlide] - slide callback 41 | * @property {function} [options.onSlideEnd] - slide end callback 42 | */ 43 | constructor (el, options) { 44 | options = options || {} 45 | 46 | this.element = el 47 | this.options = options 48 | 49 | this.onSlideEventsCount = -1 50 | this.isInteracting = false 51 | this.needTriggerEvents = false 52 | this.constructor.count = this.constructor.count || 0 53 | 54 | this.identifier = `js-${CONST.PLUGIN_NAME}-${this.constructor.count++}` 55 | 56 | this.min = utils.getFirstNumberLike(options.min, parseFloat(el.getAttribute('min')), CONST.MIN_DEFAULT) 57 | this.max = utils.getFirstNumberLike(options.max, parseFloat(el.getAttribute('max')), CONST.MAX_DEFAULT) 58 | this.value = utils.getFirstNumberLike(options.value, parseFloat(el.getAttribute('value')), this.min + (this.max - this.min) / 2) 59 | this.step = utils.getFirstNumberLike(options.step, parseFloat(el.getAttribute('step')), CONST.STEP_DEFAULT) 60 | 61 | this.percent = null 62 | this._updatePercentFromValue() 63 | this.toFixed = stepToFixed(this.step) 64 | 65 | this.range = createChild(CONST.RANGE_CLASS) 66 | this.range.id = this.identifier 67 | 68 | this.fillBg = createChild(CONST.FILL_BG_CLASS) 69 | this.fill = createChild(CONST.FILL_CLASS) 70 | this.handle = createChild(CONST.HANDLE_CLASS); 71 | 72 | ['fillBg', 'fill', 'handle'].forEach(str => this.range.appendChild(this[str])); 73 | ['min', 'max', 'step'].forEach(str => el.setAttribute(str, `${this[str]}`)) 74 | 75 | this._setValue(this.value) 76 | 77 | utils.insertAfter(el, this.range) 78 | 79 | el.style.position = 'absolute' 80 | el.style.width = '1px' 81 | el.style.height = '1px' 82 | el.style.overflow = 'hidden' 83 | el.style.opacity = '0'; 84 | 85 | ['_update', '_handleDown', '_handleMove', '_handleEnd', '_startEventListener', '_changeEventListener'] 86 | .forEach(fnName => { this[fnName] = this[fnName].bind(this) }) 87 | 88 | this._init() 89 | 90 | utils.optimizedResize.add(this._update) 91 | 92 | CONST.START_EVENTS.forEach(evName => this.range.addEventListener(evName, this._startEventListener)) 93 | 94 | el.addEventListener('change', this._changeEventListener) 95 | } 96 | 97 | /** 98 | * 99 | * @private 100 | */ 101 | _init () { 102 | this._update() 103 | this.options.onInit && this.options.onInit.call(this, this.value, this.percent, this.position) 104 | } 105 | 106 | /** 107 | * 108 | * @private 109 | */ 110 | _updatePercentFromValue () { 111 | this.percent = (this.value - this.min) / (this.max - this.min) 112 | } 113 | 114 | /** 115 | * Checks if this.identifier exists in ev.target's ancestors 116 | * @param {Event} ev 117 | * @private 118 | */ 119 | _startEventListener (ev) { 120 | const el = ev.target 121 | const identifier = this.identifier 122 | let isEventOnSlider = false 123 | 124 | utils.forEachAncestorsAndSelf(el, el => 125 | (isEventOnSlider = (el.id === identifier && !el.classList.contains(CONST.DISABLED_CLASS)))) 126 | 127 | isEventOnSlider && this._handleDown(ev) 128 | } 129 | 130 | /** 131 | * 132 | * @param {Event} ev 133 | * @param data 134 | * @private 135 | */ 136 | _changeEventListener (ev, data) { 137 | if (!((data && data.origin) === this.identifier)) { 138 | this._setPosition(this._getPositionFromValue(ev.target.value)) 139 | } 140 | } 141 | 142 | /** 143 | * 144 | * @private 145 | */ 146 | _update () { 147 | this.handleWidth = utils.getDimension(this.handle, 'offsetWidth') 148 | this.rangeWidth = utils.getDimension(this.range, 'offsetWidth') 149 | this.maxHandleX = this.rangeWidth - this.handleWidth 150 | this.grabX = this.handleWidth / 2 151 | this.position = this._getPositionFromValue(this.value) 152 | 153 | this.range.classList[this.element.disabled ? 'add' : 'remove'](CONST.DISABLED_CLASS) 154 | 155 | this._setPosition(this.position) 156 | this._updatePercentFromValue() 157 | this._emit('change') 158 | } 159 | 160 | /** 161 | * 162 | * @param {boolean} bool 163 | * @private 164 | */ 165 | _listen (bool) { 166 | const addOrRemoveListener = `${bool ? 'add' : 'remove'}EventListener` 167 | 168 | CONST.MOVE_EVENTS.forEach(evName => document && document[addOrRemoveListener](evName, this._handleMove)) 169 | CONST.END_EVENTS.forEach(evName => { 170 | document && document[addOrRemoveListener](evName, this._handleEnd) 171 | this.range[addOrRemoveListener](evName, this._handleEnd) 172 | }) 173 | } 174 | 175 | /** 176 | * @param {Event} e 177 | * @private 178 | */ 179 | _handleDown (e) { 180 | e.preventDefault() 181 | 182 | this.isInteracting = true 183 | 184 | this._listen(true) 185 | if (e.target.classList.contains(CONST.HANDLE_CLASS)) { 186 | return 187 | } 188 | 189 | const posX = evPos(e, this.range).x 190 | const rangeX = this.range.getBoundingClientRect().left 191 | const handleX = this.handle.getBoundingClientRect().left - rangeX 192 | 193 | this._setPosition(posX - this.grabX) 194 | 195 | if (posX >= handleX && posX < handleX + this.handleWidth) { 196 | this.grabX = posX - handleX 197 | } 198 | this._updatePercentFromValue() 199 | } 200 | 201 | /** 202 | * @param {Event} e 203 | * @private 204 | */ 205 | _handleMove (e) { 206 | this.isInteracting = true 207 | e.preventDefault() 208 | const posX = evPos(e, this.range).x 209 | this._setPosition(posX - this.grabX) 210 | } 211 | 212 | /** 213 | * @param {Event} e 214 | * @private 215 | */ 216 | _handleEnd (e) { 217 | e.preventDefault() 218 | 219 | this._listen(false) 220 | this._emit('change') 221 | 222 | if ((this.isInteracting || this.needTriggerEvents) && this.options.onSlideEnd) { 223 | this.options.onSlideEnd.call(this, this.value, this.percent, this.position) 224 | } 225 | this.onSlideEventsCount = 0 226 | this.isInteracting = false 227 | } 228 | 229 | /** 230 | * 231 | * @param pos 232 | * @private 233 | */ 234 | _setPosition (pos) { 235 | const value = this.isInteracting ? this._getValueFromPosition(utils.clamp(pos, 0, this.maxHandleX)) : this.value 236 | const x = this._getPositionFromValue(value) 237 | 238 | // Update ui 239 | this.fill.style.width = (x + this.grabX) + 'px' 240 | this.handle.style.webkitTransform = this.handle.style.transform = `translate(${x}px, -50%)` 241 | this._setValue(value) 242 | 243 | // Update globals 244 | this.position = x 245 | this.value = value 246 | this._updatePercentFromValue() 247 | 248 | if (this.isInteracting || this.needTriggerEvents) { 249 | if (this.options.onSlideStart && this.onSlideEventsCount === 0) { 250 | this.options.onSlideStart.call(this, this.value, this.percent, this.position) 251 | } 252 | 253 | if (this.options.onSlide) { 254 | this.options.onSlide.call(this, this.value, this.percent, this.position) 255 | } 256 | } 257 | 258 | this.onSlideEventsCount++ 259 | } 260 | 261 | /** 262 | * 263 | * @param {number} value 264 | * @returns {number} 265 | * @private 266 | */ 267 | _getPositionFromValue (value) { 268 | const percentage = (value - this.min) / (this.max - this.min) 269 | 270 | return percentage * this.maxHandleX 271 | } 272 | 273 | /** 274 | * 275 | * @param {number} pos 276 | * @returns {number} 277 | * @private 278 | */ 279 | _getValueFromPosition (pos) { 280 | const percentage = ((pos) / (this.maxHandleX || 1)) 281 | const value = this.step * Math.round(percentage * (this.max - this.min) / this.step) + this.min 282 | 283 | return Number((value).toFixed(this.toFixed)) 284 | } 285 | 286 | /** 287 | * 288 | * @param {number} value 289 | * @private 290 | */ 291 | _setValue (value) { 292 | value = utils.clamp(value, this.min, this.max) 293 | if (!(value === this.value && value === this.element.value)) { 294 | this.value = this.element.value = value 295 | this._emit('input') 296 | } 297 | } 298 | 299 | _emit (evName) { 300 | utils.emit(this.element, evName, { 301 | origin: this.identifier 302 | }) 303 | } 304 | 305 | /** 306 | * Update 307 | * 308 | * @param {Object} [values={}] like {min : Number, max : Number, value : Number, step : Number} 309 | * @param {Boolean} [triggerEvents] 310 | * @returns {RangeSlider} 311 | */ 312 | update (values, triggerEvents) { 313 | values = values || {} 314 | Object.keys(values).forEach(val => 315 | (typeof values[val] === 'string') && (values[val] = parseFloat(values[val])) 316 | ) 317 | 318 | this.needTriggerEvents = triggerEvents 319 | 320 | if (utils.isFiniteNumber(values.min)) { 321 | this.element.setAttribute('min', `${values.min}`) 322 | this.min = values.min 323 | } 324 | 325 | if (utils.isFiniteNumber(values.max)) { 326 | this.element.setAttribute('max', `${values.max}`) 327 | this.max = values.max 328 | } 329 | 330 | if (utils.isFiniteNumber(values.step)) { 331 | this.element.setAttribute('step', `${values.step}`) 332 | this.step = values.step 333 | this.toFixed = stepToFixed(values.step) 334 | } 335 | 336 | if (utils.isFiniteNumber(values.value)) { 337 | this._setValue(values.value) 338 | } 339 | 340 | this._update() 341 | this.onSlideEventsCount = 0 342 | this.needTriggerEvents = false 343 | return this 344 | } 345 | 346 | /** 347 | * 348 | */ 349 | destroy () { 350 | if (typeof window !== 'undefined') { 351 | window.removeEventListener('resize', this._update, false) 352 | } 353 | 354 | CONST.START_EVENTS.forEach(evName => this.range.removeEventListener(evName, this._startEventListener)) 355 | 356 | this.element.removeEventListener('change', this._changeEventListener) 357 | 358 | this.element.style.cssText = '' 359 | delete this.element[CONST.PLUGIN_NAME] 360 | 361 | this.range.parentNode.removeChild(this.range) 362 | } 363 | } 364 | 365 | /** 366 | * @callback RangeSlider~onInit 367 | * @param {number} value 368 | * @param {number} percent 369 | * @param {number} position 370 | */ 371 | 372 | /** 373 | * @callback RangeSlider~onSlideStart 374 | * @param {number} value 375 | * @param {number} percent 376 | * @param {number} position 377 | */ 378 | 379 | /** 380 | * @callback RangeSlider~onSlide 381 | * @param {number} value 382 | * @param {number} percent 383 | * @param {number} position 384 | */ 385 | 386 | /** 387 | * @callback RangeSlider~onSlideEnd 388 | * @param {number} value 389 | * @param {number} percent 390 | * @param {number} position 391 | */ 392 | 393 | export default RangeSlider 394 | -------------------------------------------------------------------------------- /src/styles.css: -------------------------------------------------------------------------------- 1 | .rangeslider { 2 | position: relative; 3 | display: block; 4 | cursor: pointer; 5 | height: 25px; 6 | width: 100%; 7 | } 8 | .rangeslider__fill, 9 | .rangeslider__fill__bg { 10 | display: block; 11 | position: absolute; 12 | top: 50%; 13 | height: 2px; 14 | z-index: 2; 15 | background: #29e; 16 | border-radius: 10px; 17 | will-change: width; 18 | } 19 | .rangeslider__handle { 20 | will-change: width, height, top; 21 | width: 14px; 22 | height: 14px; 23 | position: absolute; 24 | top: 50%; 25 | background: #29e; 26 | display: inline-block; 27 | z-index: 3; 28 | cursor: pointer; 29 | border: solid 2px #ffffff; 30 | border-radius: 50%; 31 | -webkit-transition: width 0.1s ease-in-out, height 0.1s ease-in-out, top 0.1s ease-in-out; 32 | transition: width 0.1s ease-in-out, height 0.1s ease-in-out, top 0.1s ease-in-out; 33 | } 34 | .rangeslider__handle:active { 35 | background: #107ecd; 36 | } 37 | .rangeslider__fill__bg { 38 | background: #ccc; 39 | width: 100%; 40 | } 41 | .rangeslider--disabled { 42 | opacity: 0.4; 43 | } 44 | -------------------------------------------------------------------------------- /src/utils.js: -------------------------------------------------------------------------------- 1 | import CE from 'custom-event' 2 | 3 | window.requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame 4 | 5 | /** 6 | * 7 | * @param val 8 | * @param min 9 | * @param max 10 | * @returns {*} 11 | */ 12 | function clamp (val, min, max) { 13 | return min < max ? (val < min ? min : val > max ? max : val) : (val < max ? max : val > min ? min : val) 14 | } 15 | 16 | /** 17 | * 18 | * @param el 19 | * @returns {boolean} 20 | */ 21 | function isHidden (el) { 22 | return el.offsetWidth === 0 || el.offsetHeight === 0 || el.open === false 23 | } 24 | 25 | /** 26 | * See {@link https://github.com/sindresorhus/number-is-nan} 27 | * @param x 28 | * @returns {boolean} 29 | */ 30 | const numberIsNan = Number.isNaN || (x => x !== x) // eslint-disable-line 31 | 32 | /** 33 | * See {@link https://github.com/sindresorhus/is-finite} 34 | * @param val 35 | * @returns {boolean} 36 | */ 37 | const isFiniteNumber = Number.isFinite || 38 | (val => !(typeof val !== 'number' || numberIsNan(val) || val === Infinity || val === -Infinity)) 39 | 40 | /** 41 | * 42 | * @param obj 43 | * @returns {*} 44 | */ 45 | function isNumberLike (obj) { 46 | return isFiniteNumber(parseFloat(obj)) || isFiniteNumber(obj) 47 | } 48 | 49 | /** 50 | * 51 | * @returns {*} 52 | */ 53 | function getFirstNumberLike () { 54 | if (!arguments.length) { 55 | return null 56 | } 57 | for (let i = 0, len = arguments.length; i < len; i++) { 58 | if (isNumberLike(arguments[i])) { 59 | return arguments[i] 60 | } 61 | } 62 | } 63 | 64 | /** 65 | * 66 | * @param el 67 | * @returns {Array} 68 | */ 69 | function getHiddenParentNodes (el) { 70 | const parents = [] 71 | let node = el.parentNode 72 | 73 | while (node && isHidden(node)) { 74 | parents.push(node) 75 | node = node.parentNode 76 | } 77 | return parents 78 | } 79 | 80 | /** 81 | * 82 | * @param element 83 | * @param key 84 | * @returns {*} 85 | */ 86 | function getDimension (element, key) { 87 | const hiddenParentNodes = getHiddenParentNodes(element) 88 | const hiddenParentNodesLength = hiddenParentNodes.length 89 | const displayProperty = [] 90 | let dimension = element[key] 91 | let i = 0 92 | let hiddenStyles 93 | 94 | // Used for native `
` elements 95 | function toggleOpenProperty (element) { 96 | if (typeof element.open !== 'undefined') { 97 | element.open = !element.open 98 | } 99 | } 100 | 101 | if (hiddenParentNodesLength) { 102 | for (i = 0; i < hiddenParentNodesLength; i++) { 103 | hiddenStyles = hiddenParentNodes[i].style 104 | // Cache the display property to restore it later. 105 | displayProperty[i] = hiddenStyles.display 106 | hiddenStyles.display = 'block' 107 | hiddenStyles.height = '0' 108 | hiddenStyles.overflow = 'hidden' 109 | hiddenStyles.visibility = 'hidden' 110 | 111 | toggleOpenProperty(hiddenParentNodes[i]) 112 | } 113 | 114 | dimension = element[key] 115 | 116 | for (i = 0; i < hiddenParentNodesLength; i++) { 117 | hiddenStyles = hiddenParentNodes[i].style 118 | toggleOpenProperty(hiddenParentNodes[i]) 119 | hiddenStyles.display = displayProperty[i] 120 | hiddenStyles.height = '' 121 | hiddenStyles.overflow = '' 122 | hiddenStyles.visibility = '' 123 | } 124 | } 125 | return dimension 126 | } 127 | 128 | /** 129 | * 130 | * @param {HtmlElement} el 131 | * @param {function} cb 132 | * @returns {Element} 133 | */ 134 | function forEachAncestorsAndSelf (el, cb) { 135 | cb(el) 136 | while (el.parentNode && !cb(el)) { 137 | el = el.parentNode 138 | } 139 | return el 140 | } 141 | 142 | /** 143 | * @param {Element} referenceNode after this 144 | * @param {Element} newNode insert this 145 | */ 146 | function insertAfter (referenceNode, newNode) { 147 | referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling) 148 | } 149 | 150 | /** 151 | * optimized windows resize using raf, timeout als fallback 152 | * See {@link https://developer.mozilla.org/en-US/docs/Web/Events/resize} 153 | */ 154 | const optimizedResize = (() => { 155 | const callbacks = [] 156 | let running = false 157 | 158 | // fired on resize event 159 | function resize () { 160 | if (!running) { 161 | running = true 162 | 163 | if (window.requestAnimationFrame) { 164 | window.requestAnimationFrame(runCallbacks) 165 | } else { 166 | setTimeout(runCallbacks, 66) 167 | } 168 | } 169 | } 170 | 171 | // run the actual callbacks 172 | function runCallbacks () { 173 | callbacks.forEach(callback => { 174 | callback() 175 | }) 176 | running = false 177 | } 178 | 179 | // adds callback to loop 180 | function addCallback (callback) { 181 | callback && callbacks.push(callback) 182 | } 183 | 184 | return { 185 | // public method to add additional callback 186 | add: callback => { 187 | !callbacks.length && window.addEventListener('resize', resize) 188 | addCallback(callback) 189 | } 190 | } 191 | })() 192 | 193 | export default { 194 | emit: function (el, name, opt) { 195 | el.dispatchEvent(new CE(name, opt)) 196 | }, 197 | isFiniteNumber, 198 | getFirstNumberLike, 199 | getDimension, 200 | insertAfter, 201 | forEachAncestorsAndSelf, 202 | clamp, 203 | optimizedResize 204 | } 205 | -------------------------------------------------------------------------------- /test/helpers/ava-setup.js: -------------------------------------------------------------------------------- 1 | require('@babel/register')({ 2 | ignore: ['node_modules/*'] 3 | }) 4 | require('@babel/polyfill') 5 | 6 | const browserEnv = require('browser-env') 7 | 8 | browserEnv() 9 | -------------------------------------------------------------------------------- /test/unit/const.js: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import CONST from '../../src/const' 3 | 4 | test('const should be an object', t => { 5 | t.is(typeof CONST, 'object') 6 | }) 7 | 8 | test('const MAX_DEFAULT should be a number', t => { 9 | t.is(typeof CONST.MAX_DEFAULT, 'number') 10 | }) 11 | -------------------------------------------------------------------------------- /test/unit/index.js: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import CONST from '../../src/const' 3 | import rangesliderJs from '../../src' 4 | 5 | const getSliderEl = (additionalAttributes = []) => { 6 | const sliderEl = document.createElement('input') 7 | sliderEl.setAttribute('data-rangeslider', '') 8 | sliderEl.setAttribute('type', 'range') 9 | additionalAttributes.forEach(attr => sliderEl.setAttribute(attr.name, attr.val)) 10 | document.body.appendChild(sliderEl) 11 | return sliderEl 12 | } 13 | 14 | test('rangesliderJs type should be a object', 15 | t => t.is(typeof rangesliderJs, 'object')) 16 | 17 | test('rangesliderJs.create should exist and be of type function', t => 18 | t.is(typeof rangesliderJs.create, 'function')) 19 | 20 | test('create should work', t => { 21 | const sliderEl = getSliderEl() 22 | 23 | rangesliderJs.create(sliderEl) 24 | 25 | t.is(sliderEl['rangeslider-js'] instanceof rangesliderJs.RangeSlider, true) 26 | }) 27 | 28 | test('create with js-options should work', async t => { 29 | const sliderEl = getSliderEl() 30 | 31 | rangesliderJs.create(sliderEl, { 32 | min: 0, 33 | max: 200, 34 | value: 40, 35 | step: 0.5 36 | }) 37 | 38 | t.is(sliderEl['rangeslider-js'].min, 0) 39 | t.is(sliderEl['rangeslider-js'].max, 200) 40 | t.is(sliderEl['rangeslider-js'].value, 40) 41 | t.is(sliderEl['rangeslider-js'].step, 0.5) 42 | 43 | sliderEl['rangeslider-js'].destroy() 44 | document.body.removeChild(sliderEl) 45 | }) 46 | 47 | test('create with html-attrs should work', async t => { 48 | const sliderEl = getSliderEl([ 49 | {name: 'min', val: -10}, 50 | {name: 'max', val: 400}, 51 | {name: 'value', val: 45}, 52 | {name: 'step', val: 2} 53 | ]) 54 | 55 | rangesliderJs.create(sliderEl) 56 | 57 | t.is(sliderEl['rangeslider-js'].min, -10) 58 | t.is(sliderEl['rangeslider-js'].max, 400) 59 | t.is(sliderEl['rangeslider-js'].value, 45) 60 | t.is(sliderEl['rangeslider-js'].step, 2) 61 | 62 | sliderEl['rangeslider-js'].destroy() 63 | document.body.removeChild(sliderEl) 64 | }) 65 | 66 | test('create with default options should work', async t => { 67 | const sliderEl = getSliderEl() 68 | 69 | rangesliderJs.create(sliderEl) 70 | 71 | t.is(sliderEl['rangeslider-js'].min, CONST.MIN_DEFAULT) 72 | t.is(sliderEl['rangeslider-js'].max, CONST.MAX_DEFAULT) 73 | t.is(sliderEl['rangeslider-js'].value, (CONST.MIN_DEFAULT + CONST.MAX_DEFAULT) / 2) 74 | t.is(sliderEl['rangeslider-js'].step, CONST.STEP_DEFAULT) 75 | 76 | sliderEl['rangeslider-js'].destroy() 77 | document.body.removeChild(sliderEl) 78 | }) 79 | 80 | test('create multiple should work', async t => { 81 | const sliderEl1 = getSliderEl() 82 | const sliderEl2 = getSliderEl() 83 | 84 | rangesliderJs.create(document.querySelectorAll('[data-rangeslider]')) 85 | 86 | t.is(sliderEl1['rangeslider-js'].max, CONST.MAX_DEFAULT) 87 | t.is(sliderEl2['rangeslider-js'].max, CONST.MAX_DEFAULT) 88 | 89 | sliderEl1['rangeslider-js'].destroy() 90 | sliderEl2['rangeslider-js'].destroy() 91 | document.body.removeChild(sliderEl1) 92 | document.body.removeChild(sliderEl2) 93 | }) 94 | 95 | test('update should work with numbers', async t => { 96 | const sliderEl = getSliderEl() 97 | 98 | rangesliderJs.create(sliderEl) 99 | 100 | sliderEl['rangeslider-js'].update({ 101 | min: -100, 102 | max: -50, 103 | value: -99, 104 | step: 0.01 105 | }) 106 | 107 | t.is(sliderEl['rangeslider-js'].min, -100) 108 | t.is(sliderEl['rangeslider-js'].max, -50) 109 | t.is(sliderEl['rangeslider-js'].value, -99) 110 | t.is(sliderEl['rangeslider-js'].step, 0.01) 111 | 112 | // bounds 113 | sliderEl['rangeslider-js'].update({value: -200}) 114 | t.is(sliderEl['rangeslider-js'].value, -100) 115 | 116 | sliderEl['rangeslider-js'].update({value: 77}) 117 | t.is(sliderEl['rangeslider-js'].value, -50) 118 | 119 | sliderEl['rangeslider-js'].destroy() 120 | document.body.removeChild(sliderEl) 121 | }) 122 | 123 | test('update should work with strings', async t => { 124 | const sliderEl = getSliderEl() 125 | 126 | rangesliderJs.create(sliderEl) 127 | 128 | sliderEl['rangeslider-js'].update({ 129 | min: '-100', 130 | max: '-50', 131 | value: '-99', 132 | step: '0.01' 133 | }) 134 | 135 | t.is(sliderEl['rangeslider-js'].min, -100) 136 | t.is(sliderEl['rangeslider-js'].max, -50) 137 | t.is(sliderEl['rangeslider-js'].value, -99) 138 | t.is(sliderEl['rangeslider-js'].step, 0.01) 139 | 140 | // bounds 141 | sliderEl['rangeslider-js'].update({value: '-200'}) 142 | t.is(sliderEl['rangeslider-js'].value, -100) 143 | 144 | sliderEl['rangeslider-js'].update({value: '77'}) 145 | t.is(sliderEl['rangeslider-js'].value, -50) 146 | 147 | sliderEl['rangeslider-js'].destroy() 148 | document.body.removeChild(sliderEl) 149 | }) 150 | 151 | test('destroy should work', t => { 152 | const sliderEl = getSliderEl() 153 | rangesliderJs.create(sliderEl) 154 | 155 | sliderEl['rangeslider-js'].destroy() 156 | 157 | t.is(sliderEl['rangeslider-js'] instanceof rangesliderJs.RangeSlider, false) 158 | document.body.removeChild(sliderEl) 159 | }) 160 | -------------------------------------------------------------------------------- /test/unit/utils.js: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import utils from '../../src/utils' 3 | 4 | test('utils should be an object', t => { 5 | t.is(typeof utils, 'object') 6 | }) 7 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const config = require('./config/index') 3 | const ProgressBarPlugin = require('progress-bar-webpack-plugin') 4 | const webpack = require('webpack') 5 | const HtmlWebpackPlugin = require('html-webpack-plugin') 6 | const FriendlyErrors = require('friendly-errors-webpack-plugin') 7 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin 8 | 9 | const isDev = process.env.NODE_ENV === 'development' 10 | const isProd = process.env.NODE_ENV === 'production' 11 | const isTest = process.env.NODE_ENV === 'testing' 12 | 13 | const projectRoot = path.resolve(__dirname) 14 | 15 | const assetsPath = (_path) => { 16 | const assetsSubDirectory = isProd 17 | ? config.build.assetsSubDirectory 18 | : config.dev.assetsSubDirectory 19 | return path.posix.join(assetsSubDirectory, _path) 20 | } 21 | 22 | const conf = { 23 | entry: {}, 24 | resolveLoader: { 25 | modules: [ 26 | `${projectRoot}/node_modules` 27 | ] 28 | }, 29 | resolve: { 30 | extensions: ['.js', '.css'], 31 | modules: [ 32 | `${projectRoot}/node_modules` 33 | ] 34 | }, 35 | module: { 36 | rules: [{ 37 | enforce: 'pre', 38 | test: /\.js$/, 39 | loader: 'eslint-loader', 40 | options: { 41 | formatter: require('eslint-friendly-formatter') 42 | } 43 | }, { 44 | test: /\.js$/, 45 | loader: 'babel-loader' 46 | }] 47 | }, 48 | plugins: [ 49 | new webpack.DefinePlugin({ 50 | DEV: isDev, 51 | PROD: isProd, 52 | TEST: isTest 53 | }), 54 | new ProgressBarPlugin(), 55 | new FriendlyErrors() 56 | ] 57 | } 58 | 59 | if (isDev) { 60 | conf.mode = 'development' 61 | conf.devtool = '#source-map' 62 | conf.entry['rangeslider-js'] = `${projectRoot}/src/dev.js` 63 | conf.module.rules.push({ 64 | test: /\.css$/, 65 | use: ['style-loader', 'css-loader'] 66 | }) 67 | conf.plugins.push( 68 | new HtmlWebpackPlugin({ 69 | filename: 'index.html', 70 | template: `dev.html`, 71 | inject: true 72 | }) 73 | ) 74 | } else { 75 | conf.mode = 'production' 76 | conf.entry = { 77 | 'rangeslider-js.min': `${projectRoot}/src/index.js` 78 | } 79 | conf.devtool = false 80 | conf.output = { 81 | path: config.build.assetsRoot, 82 | filename: assetsPath('[name].js'), 83 | chunkFilename: assetsPath('[id].js'), 84 | library: 'rangesliderJs', 85 | libraryExport: 'default', 86 | libraryTarget: 'umd' 87 | } 88 | conf.plugins.push( 89 | new HtmlWebpackPlugin({ 90 | filename: 'index.html', 91 | template: 'prod.html', 92 | inject: false 93 | }), 94 | new webpack.LoaderOptionsPlugin({ 95 | minimize: true, 96 | debug: false 97 | }) 98 | ) 99 | if (config.build.bundleAnalyzerReport) { 100 | conf.plugins.push(new BundleAnalyzerPlugin()) 101 | } 102 | } 103 | 104 | module.exports = conf 105 | --------------------------------------------------------------------------------