rangetouch
Advanced tools
Comparing version 1.0.2 to 1.0.3
# Changelog | ||
## v1.0.3 | ||
- Fixed error if no `<input type="range">` found | ||
- CustomEvent polyfill no longer effects the global scope | ||
- AddCSS option to set whether to add helpful CSS to the page | ||
## v1.0.2 | ||
- More clean up | ||
## v1.0.1 | ||
@@ -4,0 +12,0 @@ - Clean up |
@@ -1,1 +0,1 @@ | ||
!function(t,e){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e(t,document):"function"==typeof define&&define.amd?define(null,function(){e(t,document)}):t.rangetouch=e(t,document)}("undefined"!=typeof window?window:this,function(t,e){"use strict";function n(t){return t instanceof HTMLElement&&t.classList.contains(l.selectors.disabled)}function o(t,e,n){t.addEventListener(e,n,!1)}function i(t){var e=(""+t).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);return e?Math.max(0,(e[1]?e[1].length:0)-(e[2]?+e[2]:0)):0}function u(t,e){if(e<1){var n=i(e);return parseFloat(t.toFixed(n))}return Math.round(t/e)*e}function r(t){var e,n=t.target,o=t.changedTouches[0],i=parseFloat(n.getAttribute("min"))||0,r=parseFloat(n.getAttribute("max"))||100,a=parseFloat(n.getAttribute("step"))||1,c=r-i,s=n.getBoundingClientRect(),d=100/s.width*(l.thumbWidth/2)/100;return e=100/s.width*(o.clientX-s.left),e<0?e=0:e>100&&(e=100),e<50?e-=(100-2*e)*d:e>50&&(e+=2*(e-50)*d),i+u(c*(e/100),a)}function a(t){l.enabled&&"range"===t.target.type&&!n(t.target)&&(t.preventDefault(),t.target.value=r(t),s(t.target,t.type===l.events.end?"change":"input"))}function c(){o(e.body,l.events.start,a),o(e.body,l.events.move,a),o(e.body,l.events.end,a)}function s(t,e,n){t.dispatchEvent(new CustomEvent(e,n))}function d(){return[l.selectors.range,":not(.",l.selectors.disabled,")"].join("")}var l={enabled:!0,selectors:{range:'[type="range"]',disabled:"rangetouch--disabled"},thumbWidth:15,events:{start:"touchstart",move:"touchmove",end:"touchend"}};return function(){if("ontouchstart"in e.documentElement){for(var t=e.querySelectorAll(d()),n=t.length-1;n>=0;n--)t[n].style.touchAction="manipulation",t[n].style.webkitUserSelect="none";c()}}(),{set:function(t,e){l[t]=e}}}),function(){"use strict";function t(t,e){e=e||{bubbles:!1,cancelable:!1,detail:void 0};var n=document.createEvent("CustomEvent");return n.initCustomEvent(t,e.bubbles,e.cancelable,e.detail),n}if("function"==typeof window.CustomEvent)return!1;t.prototype=window.Event.prototype,window.CustomEvent=t}(); | ||
!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=t(e,document):"function"==typeof define&&define.amd?define(null,function(){t(e,document)}):e.rangetouch=t(e,document)}("undefined"!=typeof window?window:this,function(e,t){"use strict";function n(){i(t.body,l.events.start,c),i(t.body,l.events.move,c),i(t.body,l.events.end,c)}function o(){var e=t.createElement("style");return e.appendChild(t.createTextNode("")),t.head.appendChild(e),e.sheet}function r(){return[l.selectors.range,":not(",l.selectors.disabled,")"].join("")}function a(e){return e instanceof HTMLElement&&e.classList.contains(l.selectors.disabled)}function i(e,t,n){e.addEventListener(t,n,!1)}function u(e){var t=(""+e).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);return t?Math.max(0,(t[1]?t[1].length:0)-(t[2]?+t[2]:0)):0}function d(e,t){if(t<1){var n=u(t);return parseFloat(e.toFixed(n))}return Math.round(e/t)*t}function s(e){var t,n=e.target,o=e.changedTouches[0],r=parseFloat(n.getAttribute("min"))||0,a=parseFloat(n.getAttribute("max"))||100,i=parseFloat(n.getAttribute("step"))||1,u=a-r,s=n.getBoundingClientRect(),c=100/s.width*(l.thumbWidth/2)/100;return t=100/s.width*(o.clientX-s.left),t<0?t=0:t>100&&(t=100),t<50?t-=(100-2*t)*c:t>50&&(t+=2*(t-50)*c),r+d(u*(t/100),i)}function c(e){l.enabled&&"range"===e.target.type&&!a(e.target)&&(e.preventDefault(),e.target.value=s(e),e(e.target,e.type===l.events.end?"change":"input"))}var l={enabled:!0,addCSS:!0,thumbWidth:15,selectors:{range:'[type="range"]',disabled:".rangetouch--disabled"},events:{start:"touchstart",move:"touchmove",end:"touchend"}};return function(){if("ontouchstart"in t.documentElement){var e=r();if(t.querySelectorAll(e).length){if(l.addCSS){var a=t.styleSheets;(a.length?a[0]:o()).insertRule(e+" { user-select: none; -webkit-user-select: none; touch-action: manipulation; }",0)}n()}}}(),{set:function(e,t){l[e]=t}}}); |
{ | ||
"name": "rangetouch", | ||
"version": "1.0.2", | ||
"version": "1.0.3", | ||
"description": "A super tiny library to make input type='range' sliders work better on touch devices", | ||
@@ -5,0 +5,0 @@ "homepage": "https://rangetouch.com", |
@@ -21,3 +21,3 @@ # RangeTouch | ||
``` | ||
It will automatically bind to all `<input type="range">` elements, even newlt injected ones. | ||
It will automatically bind to all `<input type="range">` elements, even newlt injected ones. | ||
@@ -27,7 +27,7 @@ ### CDN | ||
```html | ||
<script src="https://cdn.rangetouch.com/1.0.2/rangetouch.js"></script> | ||
<script src="https://cdn.rangetouch.com/1.0.3/rangetouch.js"></script> | ||
``` | ||
### Node Package Manager (NPM) | ||
[![npm version](https://badge.fury.io/js/rangetouch.svg)](https://badge.fury.io/js/rangetouch) | ||
[![npm version](https://badge.fury.io/js/rangetouch.svg)](https://badge.fury.io/js/rangetouch) | ||
@@ -53,5 +53,7 @@ Using NPM, you can grab RangeTouch: | ||
If you're customizing your range inputs (easily done - see the demo for an example) and you change the size of the thumb handle, you should specify (in pixels) this after including the script: | ||
```javascript | ||
window.rangetouch.set("thumbWidth", 15); | ||
``` | ||
This value is used as part of the calculation to determine the value the users selects when touching the range track. Unfortunately as JavaScript can't access the shadow DOM, this value can't be automatically determined. I would recommend customisation (and setting the size of the thumb) given all OS and browser combinations seem to render the control differently (as per usual). | ||
@@ -74,5 +76,5 @@ | ||
Thanks to [Fastly](https://www.fastly.com/) for providing the CDN services. | ||
Thanks to [Fastly](https://www.fastly.com/) for providing the CDN services. | ||
## Copyright and License | ||
[The MIT license](license.md). |
// ========================================================================== | ||
// rangetouch.js v1.0.2 | ||
// rangetouch.js v1.0.3 | ||
// Making <input type="range"> work on touch devices | ||
@@ -30,7 +30,8 @@ // https://github.com/selz/rangetouch | ||
enabled: true, | ||
addCSS: true, | ||
thumbWidth: 15, | ||
selectors: { | ||
range: '[type="range"]', | ||
disabled: 'rangetouch--disabled' | ||
disabled: '.rangetouch--disabled' | ||
}, | ||
thumbWidth: 15, | ||
events: { | ||
@@ -43,2 +44,88 @@ start: 'touchstart', | ||
// Setup | ||
function setup() { | ||
// Bail if not a touch enabled device | ||
if (!('ontouchstart' in document.documentElement)) { | ||
return; | ||
} | ||
// Build selector | ||
var selector = getSelector(); | ||
// Find all inputs | ||
var inputs = document.querySelectorAll(selector); | ||
// Bail if nothing to setup | ||
if (!inputs.length) { | ||
return; | ||
} | ||
// Add useful CSS | ||
if (settings.addCSS) { | ||
var stylesheets = document.styleSheets; | ||
var stylesheet = stylesheets.length ? stylesheets[0] : createStyleSheet(); | ||
stylesheet.insertRule(selector + ' { user-select: none; -webkit-user-select: none; touch-action: manipulation; }', 0); | ||
} | ||
// Listen for events | ||
listeners(); | ||
} | ||
// Event listeners | ||
function listeners() { | ||
on(document.body, settings.events.start, set); | ||
on(document.body, settings.events.move, set); | ||
on(document.body, settings.events.end, set); | ||
} | ||
// Create a CSS stylesheet | ||
function createStyleSheet() { | ||
var style = document.createElement("style"); | ||
style.appendChild(document.createTextNode("")); | ||
document.head.appendChild(style); | ||
return style.sheet; | ||
} | ||
// Trigger event | ||
function event(element, type, properties) { | ||
// Bail if no element | ||
if (!element || !type) { | ||
return; | ||
} | ||
// Create CustomEvent constructor | ||
var CustomEvent; | ||
if (typeof window.CustomEvent === 'function') { | ||
CustomEvent = window.CustomEvent; | ||
} else { | ||
// Polyfill CustomEvent | ||
// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#Polyfill | ||
CustomEvent = function(event, params) { | ||
params = params || { | ||
bubbles: false, | ||
cancelable: false, | ||
detail: undefined | ||
}; | ||
var custom = document.createEvent('CustomEvent'); | ||
custom.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); | ||
return custom; | ||
}; | ||
CustomEvent.prototype = window.Event.prototype; | ||
} | ||
// Create and dispatch the event | ||
var event = new CustomEvent(type, { | ||
bubbles: true, | ||
detail: properties | ||
}); | ||
// Dispatch the event | ||
element.dispatchEvent(event); | ||
} | ||
// Get the selector for the range | ||
function getSelector() { | ||
return [settings.selectors.range, ":not(", settings.selectors.disabled, ")"].join(""); | ||
} | ||
// Check if element is disabled | ||
@@ -49,2 +136,3 @@ function isDisabled(element) { | ||
} | ||
return false; | ||
@@ -76,3 +164,3 @@ } | ||
// Round to the nearest step | ||
function roundToStep(number, step) { | ||
function round(number, step) { | ||
if (step < 1) { | ||
@@ -86,3 +174,3 @@ var places = getDecimalPlaces(step); | ||
// Get the value based on touch position | ||
function getValue(event) { | ||
function get(event) { | ||
var input = event.target; | ||
@@ -118,7 +206,7 @@ var touch = event.changedTouches[0]; | ||
// Find the closest step to the mouse position | ||
return min + roundToStep(delta * (percent / 100), step); | ||
return min + round(delta * (percent / 100), step); | ||
} | ||
// Update range value based on position | ||
function setValue(event) { | ||
function set(event) { | ||
// If not enabled, bail | ||
@@ -133,45 +221,11 @@ if (!settings.enabled || event.target.type !== 'range' || isDisabled(event.target)) { | ||
// Set value | ||
event.target.value = getValue(event); | ||
event.target.value = get(event); | ||
// Trigger input event | ||
_triggerEvent(event.target, (event.type === settings.events.end ? 'change' : 'input')); | ||
event(event.target, (event.type === settings.events.end ? 'change' : 'input')); | ||
} | ||
// Event listeners | ||
function listeners() { | ||
on(document.body, settings.events.start, setValue); | ||
on(document.body, settings.events.move, setValue); | ||
on(document.body, settings.events.end, setValue); | ||
} | ||
// Run setup automatically | ||
setup(); | ||
// Trigger event | ||
function _triggerEvent(element, eventName, properties) { | ||
element.dispatchEvent(new CustomEvent(eventName, properties)); | ||
} | ||
// Get the selector for the range | ||
function getSelector() { | ||
return [settings.selectors.range, ":not(.", settings.selectors.disabled, ")"].join(""); | ||
} | ||
// Expose setup function | ||
(function() { | ||
// Bail if not a touch device | ||
if (!('ontouchstart' in document.documentElement)) { | ||
return; | ||
} | ||
// Find all inputs | ||
var inputs = document.querySelectorAll(getSelector()); | ||
// Set touchAction to prevent delays | ||
for (var i = inputs.length - 1; i >= 0; i--) { | ||
inputs[i].style.touchAction = 'manipulation'; | ||
inputs[i].style.webkitUserSelect = 'none'; | ||
} | ||
// Listen for events | ||
listeners(); | ||
})(); | ||
return { | ||
@@ -183,27 +237,1 @@ set: function(setting, value) { | ||
})); | ||
// Custom event polyfill | ||
// --------------------------------- | ||
// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent | ||
(function() { | ||
'use strict'; | ||
if (typeof window.CustomEvent === 'function') { | ||
return false; | ||
} | ||
function CustomEvent(event, params) { | ||
params = params || { | ||
bubbles: false, | ||
cancelable: false, | ||
detail: undefined | ||
}; | ||
var evt = document.createEvent('CustomEvent'); | ||
evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); | ||
return evt; | ||
} | ||
CustomEvent.prototype = window.Event.prototype; | ||
window.CustomEvent = CustomEvent; | ||
})(); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
74871
36
739
77