Closed JedWatson closed 9 years ago
Progress update: scroll events don't fire during momentum scrolling, only (what I am going to call) "touch-tracked" scrolling. fastclick seems to implement a solution for this by detecting changes to the scrollTop
in parent elements, I'm going to see if I have any luck porting that.
I ended up being able to fix this by calculating the current scroll position of the tappable's scroll parents on touchStart
and comparing it to the scroll position after touchEnd
.
Initially I used a setTimeout
to allow the DOM elements to update (basically, no scroll event fires during momentum scrolling, but the scrollTop
is updated when momentum scrolling is halted), however the more robust solution turned out to be checking the final scroll offset and firing the onTap
event in the callback of the tappable's setState({ active: false })
.
I can't find any issues with this approach on iOS, and happily it seems to also resolve an edge case where the tappable setState
would (rarely) conflict with TouchstoneJS transitions, breaking the CSSTransitionGroup
animation.
Win!
On iOS, the tap event still fires when I do touch-to-stop-scroll on the <body>
(not using -webkit-overflow-scrolling:touch
).
Although the scrolling has higher friction without -webkit-overflow-scrolling:touch
, I still find it annoying by the accidental taps.
@steverandy did you find a solution to that?
@JedWatson No luck.
@slorber might have a solution https://github.com/JedWatson/react-tappable/issues/55
@steverandy I'm not sure to understand exactly your problem.
Isn't the @JedWatson solution to prevent tap events to fire in case of momentum scrolling stopped? Your problem only happens to body?
My issue is probably a duplicate of this one and also references FastClick implementation so not sure it brings anything to the table
Hi, maybe my 2 cents can help here. I don't use react or any other Dom bloater, so I'll drop some javascript to show how this can be resolved.
The issue will be persistent on both ios and android devices. The reason is momentum scrolling is a native function, the os waits 200ms to see if preventdefault has been set. If not, all touch events to the dom is suspended and the device handles the native scroll.
So the solution is quite simple, catch the tap within 200ms. Here is some code for how I catch a tap on a momentum scroll surface.
element.addEventListener('touchstart', function(e)) {
var target = this;
var handler = function(evt) {
e.preventDefault();
e.stopImmediatePropagation();
evt.preventDefault();
evt.stopImmediatePropagation();
/*
Your tap event handler code here
*/
};
target.addEventListner('touchend', handler);
setTimeout(function() {
target.removeEventListener('touchend', handler)
}, 150);
});
Hope this helps :) happy coding..
@TNT-RoX The problem is not really to catch a tap during a momentum scroll, but rather to know that a tap has been done during a momentum scroll.
IMHO your code only permits to catch a tap, but does not permit to know weither or not this tap happens during a momentum scroll
In native mobile apps, touching a scrollable container while momentum scrolling is in effect will immediately stop the scroll momentum, and prevent any tap events from firing on the elements inside the container.
(by scrollable container, I mean an element with
-webkit-overflow-scrolling:touch
applied)Currently,
react-tappable
doesn't know that a momentum scroll is in progress, so it will treat the interaction like a normal tap event (which leads to a really broken user experience).I'm currently investigating whether we can detect scroll events in any way, and block the tap correctly. No idea (yet) how I'm actually going to fix this though.
Hi! Did you fix this issue? I ask cause I want exactly opposite. In my app I need my users to have an opportunity to tap while scrolling, but as you've said first tap stops the scroll and only after user can do what he wanted. May be if u didnt fix that I can use yr library. Or may be I can use version before this exact fix.
In native mobile apps, touching a scrollable container while momentum scrolling is in effect will immediately stop the scroll momentum, and prevent any tap events from firing on the elements inside the container.
(by scrollable container, I mean an element with
-webkit-overflow-scrolling:touch
applied)Currently,
react-tappable
doesn't know that a momentum scroll is in progress, so it will treat the interaction like a normal tap event (which leads to a really broken user experience).I'm currently investigating whether we can detect scroll events in any way, and block the tap correctly. No idea (yet) how I'm actually going to fix this though.