sampotts / rangetouch Goto Github PK
View Code? Open in Web Editor NEWA super tiny library to make `<input type='range'>` sliders work better on touch devices
Home Page: https://rangetouch.com
License: MIT License
A super tiny library to make `<input type='range'>` sliders work better on touch devices
Home Page: https://rangetouch.com
License: MIT License
Since you said
"If you find anything weird with RangeTouch, please let us know using the GitHub issues tracker and be descriptive on how to reproduce, expected result, the browser (and version) used, etc."
I figured I might as well report the problem I've been struggling with for the past few hours.
I have a simple range element like this: <input type="range" id="position" name="position" step="1" min="0" max="100" value="1" title="Rewind by clicking anywhere on this red slider" data-useDiffFromNow="false"/>
And this Tippy.js 5.0.1 code works on both desktop and mobile:
(function () {
var $ = require('jquery');
const tippy = require('tippy.js').default;//https://atomiks.github.io/tippyjs/ version 5.0.1 https://stackoverflow.com/a/57862794/470749 and https://github.com/atomiks/tippyjs/issues/596
$(document).ready(function () {
const selector = 'input[type="range"]';
const tippySettings = {//https://atomiks.github.io/tippyjs/ version 5.0.1 https://atomiks.github.io/tippyjs/all-props/ and https://github.com/atomiks/tippyjs/issues/596
animation: 'fade', //Default = "fade". Tippy 5.0.1 elements use a simple CSS fade transition by default. Extra animations need to be imported separately. https://atomiks.github.io/tippyjs/animations/
arrow: true,
content(reference) {
const title = reference.getAttribute('title');
reference.removeAttribute('title');
return title;
},
delay: 0, //Delay in ms once a trigger event is fired before a tippy shows or hides.
duration: [0, 1500], // Array [show, hide] Default is [275, 250]. Duration of the CSS transition animation in ms. Possibles values: number, [number, number] = [show, hide].
inertia: true, //adds an elastic inertial effect to the tippy, which is a limited CSS-only way to mimic spring physics.
onHide(instance) {
console.log('hiding');
},
onShown(instance) {
console.log('onShown');
},
touch: true, //Default = true. Determines if the tippy displays if the user is currently using touch input. Possible values: boolean, "hold", ["hold", number]. Use "hold" to use touch listeners instead, and e.g. ["hold", 500] to simulate "long press" behavior.
trigger: "mouseenter focus click manual", //The events (each separated by a space) which cause a tippy to show. Possible values: "mouseenter", "focus", "click", "manual". "mouseenter focus click manual"
};
const el = document.querySelectorAll(selector);
const instance = tippy(el, tippySettings);
});
})();
But then if I try to add const range = new window.RangeTouch(selector);//v2.0.0
right after the tippy()
line:
I wonder if this issue isn't limited to a conflict with Tippy; I wonder if RangeTouch is preventing events from propagating in a way that they need to in order for other libraries to work?
Thanks for your library (I can't believe mobile browsers still haven't built in this functionality! ๐คฆ), and thanks for you help.
After building some nice slider interactions with React, I find that it doesn't work on iOS.
I tried importing rangetouch from the CDN into my project, but it didn't seem to have the desired effect.
Any suggestions on working with rangetouch and shadowdom?
Hi,
I would like to use rangetouch only on specific input ranges. This makes sense if I just want to fix some of the range inputs, but not all of them.
Reason: I've added the plyr.io plugin in a site, but they've had some custom input ranges aswell. In order not to break these other modules, I wanted to have the fix only on my input ranges, which I have defined in the settings of rangetouch.
So, my sugesstions:
document.addEventListener("DOMContentLoaded", function () {
// Run setup automatically
setup();
});
- if (!settings.enabled || event.target.type !== 'range' || isDisabled(event.target)) {
+ if (!settings.enabled || event.target.type !== 'range' || isDisabled(event.target) || !event.target.matches(settings.selectors.range)) {
return;
}
With this, you can setup the rangetouch via the settings:
addCSS: true,
thumbWidth: 15,
selectors: {
- range: '[type="range"]',
+ range: '.plyr-container [type="range"]',
disabled: '.rangetouch--disabled'
},
TBD: Shouldn't the selector/settings via constructor be configurable, so you can actually call the rangetouch plugin when you need it with special selectors?
Hi,
I was trying to implement the rangetouch to my Angular 7 project but i couldn't succeed maybe you have some ideas that might help me.
I installed the rangetouch using npm install rangetouch and when i tried to import it into my component (like its on npmjs.com - import RangeTouch from 'rangetouch') i got an error saying:
Could not find declaration file for module 'rangetouch'. Try installing @types/rangetouch
I tried going for npm install @types/rangetouch but got some errors
I tried including the script directly into the HTML using <script> tag, and i saw there was a difference in the HTMLInputElement, the slider took some inline css after including the script in the HTML but im not sure if thats all it needs to be done, i tried the slider on my iPhone 6s after deploying like that and it still doesn't work.
Do you have any ideas about this?
I'm not sure if im posting this on the right place,
Thanks in advance
It should detect the range input element's orientation from its height and width and adjust the touch event logic accordingly.
We've been using range touch and noticed issues from iOS 11.3 and on. The issue is that after dragging the slider, all click events have the range input as target and source, no matter where on the page.
This might or might not be an issue with rangetouch, but removing rangetouch fixed this issue for us.
I've faced with a problem.
When the user opens the page on a mobile device or even in Google Chrome in a mobile device mode (I've used option iPad Pro), there is an error:
rangetouch.js:54 Uncaught DOMException: Failed to execute 'insertRule' on 'CSSStyleSheet': Failed to insert the rule.
The exact rule is
[type="range"]:not(.rangetouch--disabled) { user-select: none; -webkit-user-select: none; touch-action: manipulation; }
I don't see anything wrong in this rule.
I've investigated this guide https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/insertRule, but there is nothing about this problem. I've tried to replace index 0 on stylesheet.cssRules.length and it helped. Not clear why exactly is it but it works.
If somebody can explain the problem in a better way, you're welcome!
Finally, the updated line looks like:
stylesheet.insertRule(getSelector() + ' { user-select: none; -webkit-user-select: none; touch-action: manipulation; }', stylesheet.cssRules.length);
First of all, this rangetouch
is cool.
But when I read your source code, I feel confused on this statement:
// Trigger input event
_triggerEvent(event.target, (event.type === settings.events.end ? 'change' : 'input'));
As my issue title says, I don't know why you dispatch events: change
/ input
?
Maybe these means different to input[type=range]
?
Hi! ๐
Firstly, thanks for your work on this project! ๐
Today I used patch-package to patch [email protected]
for the project I'm working on.
Here is the diff that solved my problem:
diff --git a/node_modules/rangetouch/src/js/rangetouch.js b/node_modules/rangetouch/src/js/rangetouch.js
index e17d469..7c137aa 100644
--- a/node_modules/rangetouch/src/js/rangetouch.js
+++ b/node_modules/rangetouch/src/js/rangetouch.js
@@ -185,7 +185,7 @@ class RangeTouch {
}
// Prevent text highlight on iOS
- event.preventDefault();
+ event.cancelable && event.preventDefault();
// Set value
// eslint-disable-next-line no-param-reassign
This issue body was partially generated by patch-package.
On touch device the "thumb" moves up-down per the touch on the left-right line, as opposed to up-down track, as it should (I hope this made sense).
Fixed it in my own version, will have to see if I have time for PR.
Fix pretty much:
where it says this from around line 176 in src/js/rangetouch.js:
// Determine left percentage
percent = ((100 / clientRect.width) * (touch.clientX - clientRect.left));
put this after it:
// Determine top percentage
percent = ((100 / clientRect.height) * ((clientRect.height-touch.clientY) -(clientRect.top)));
percent = 100-((100 / (clientRect.height)) * (touch.clientY-clientRect.top))
percent = 100 - 100 / clientRect.height * (touch.clientY - clientRect.top);
of course you would need some way (maybe conf flag) to decide which value to use
you'll maybe want to set also
window.rangetouch.set("thumbWidth", 0);
I add this package at Angular 7 project
But, I had a error like this in executing AOT build ( $ ng build --prod --named-chunks --verbose --build-optimizer=false --source-map
)
Unexpected token: punc ()) [./node_modules/rangetouch/src/js/utils/numbers.js:15,0]
I think this error comes from Math.max
method
And I avoid error by removing comma from numbers.js L:14
return Math.max(
0,
// Number of digits right of decimal point.
(match[1] ? match[1].length : 0) -
// Adjust for scientific notation.
(match[2] ? +match[2] : 0),
);
return Math.max(
0,
// Number of digits right of decimal point.
(match[1] ? match[1].length : 0) -
// Adjust for scientific notation.
(match[2] ? +match[2] : 0) // <-- remove comma and build success
);
Thank you for great project !
Hi,
I'm using Material Design Light as a framework. However adding rangetouch to my code doesn't seem to have much effect on touch devices (in contrary of your own demo).
Any idea what can be the cause? I've already added a bigger thumbwidth.
My demo: http://dev.kasperkamperman.com/localremote/index.html
Code of the demo:
https://github.com/kasperkamperman/Particle-RGB-RemoteControl/tree/master/web-code/RGB%20CloudRemote
Line 53 in js/rangetouch.js seems to cause the following error in Chrome:
Uncaught DOMException: Failed to execute 'insertRule' on 'CSSStyleSheet': Cannot access StyleSheet to insertRule
Browser: Version 67.0.3396.87 (Official Build) (64-bit)
iOS: 10.13.3
Not really sure why. I just fixed it by simply not using insertRule. From what I could quickly find is that the first item of the stylesheet can't be found.
var style = document.createElement('style'); var css = getSelector() + ' { user-select: none; -webkit-user-select: none; touch-action: manipulation; }'; style.type = 'text/css'; if (style.styleSheet) { style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); } var headElement = document.head; headElement.appendChild(style);
I just found out that the way I was using Rangetouch broke my site for about a week.
I guess I accidentally moved require("rangetouch/dist/rangetouch");
to before $(document).ready(function () {
.
And I didn't have it within a try/catch
.
What would have been nice is if Rangetouch wouldn't cause an exception (causing all my other javascript to fail) just because at the time of it being called there was no input range rendered on the page.
Thanks so much for your cool tool!
I'm now successfully using it like this:
$(document).ready(function () {
try {
require("rangetouch/dist/rangetouch");//This must be called *after* $(document).ready() https://rangetouch.com/ https://github.com/sampotts/rangetouch
} catch (e) {
console.log(e);
}
...
rangetouch/src/js/rangetouch.js
Lines 52 to 54 in 46e6b12
This violates the CSSOM spec:
The insertRule(rule, index) method must run the following steps:
If the origin-clean flag is unset, throw a SecurityError exception.
Return the result of invoking insert a CSS rule rule in the CSS rules at index.
https://drafts.csswg.org/cssom/#dom-cssstylesheet-insertrule
And breaks in Firefox (which follows the spec).
This is the opposite of an issue. I just wanted to say this is a beautiful little library. The code is immaculate and so easy to follow. Saved me big time in a pinch. Really appreciate the craft in this
iOS 10.3
Safari
Given I import rangetouch
using a script
tag in the HTML page
And I interact with my <input type="range>" The
thumb` moves but the position doesn't update after releasing
And I get console errors
Error:
TypeError: e is not a function. (In 'e(e.target,e.type===l.events.end?"change":"input")', 'e' is an instance of TouchEvent)
c โ rangetouch.js:1:1405
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.