I have a UIWebView containing a <ul> with overflow:scroll and -webkit-overflow-scrolling: touch set.
When a user interacts with the element and the touchend event fires I want to know if this is the end of a drag/pan or the beginning of momentum scroll due to a swipe.
Is this possible?
The reason I want this is so that when the drag or momentum scroll has finished, I can line up an <li> at a certain point.
Basic setup without solution in this codepen.
I tried using Hammer js to detect swipe and pan gestures, but this stops momentum scrolling from occurring on the element as far as I can tell.
Related
I have built a carousel that disables vertical scroll if scrolling horizontally on the page, and disables horizontal scroll of the carousel if scrolling vertically on the page. This works as intended on Android but not on iOS.
I'm noticing on iOS that when I look at the dev tools (using browserstack to spoof) I'm getting multiple event cycles firing (touch start, touch move, touch end) if the user swipes. They always fire as a complete set. They all fire even if the user hasn't actually removed their finger. The longer the swipe, the more cycles of these events fire. Why is this happening? My theory is that this multi fire is the problem for why my disable scrolling functions aren't working.
I am trying to get a div to go from 100% opacity to 0% opacity on scroll.
I made this Fiddle and it works great in a web browser, just as I'd hope. It works in mobile browsers too, but with one horrible downside.
var divs = $('.cover_image');
$(window).on('scroll', function() {
var st = $(this).scrollTop();
divs.css({
'opacity': (1 - st / 40)
});
});
(What is happening in the fiddle is the top div is going to opacity:0 as you scroll, revealing another div below it with the same background-image, but blurred. Creating the impression the same image is blurring the more you scroll)
In a web browser as you scroll the div drops in opacity progressively with a fade like affect which is great.
However in a mobile browser the change of opacity doesn't take effect until you release your finger from the the screen. So there is no progressive change of opacity. It only makes the changes visually as you release your finger from the screen, not as you scroll.
Is there a solution for this? I have tried adding in scrolling touch to my css, but it doesn't make a difference.
-webkit-overflow-scrolling: touch
Scrolling distance on mobile works very different from desktop. Even if you detect each step in the touch event, this is only half the truth. When the user releases, the site will continue to scroll for a bit while deaccelerating. This is called momentum scroll and will in most cases not be picked up by the touch event.
There are to my knowledge no perfect solution to this, since different devices handle scroll and touch very differently. There are however a few options you could look into.
Scrolling libraries
There are libraries to help you solve this problem. For instance one called scrollability that emulates scrolling to work more consistently.
Scrollability adds a good imitation of iOS native scrolling to your
mobile web apps.
Scrollability is a single script, it's small, and it has no external
dependencies. Drop it into your page, add a few CSS classes to
scrollable elements, and scroll away.
Ignore the scroll completely
Don't look at the touch or scroll events. Instead use setInterval or requestAnimationFrame with desired frequency that reports the pages current position (document.documentElement.scrollTop) at all time. Base your animation on this value instead of scroll or touch events. You might want to limit this to touch devices since it's not needed for desktop.
Write your own scroll functionality
Disable scrolling and make your own, without for instance momentum scroll, that is suited for your needs. Note that the scroll event is usually disabled on desktop if you disable scroll, but mousewheel works. I have been down this path and I would not recommend it. Instead you should probably go with the library approach at the top.
I have multiple div which scroll at the same time. I had a css property to have the inertia effect on my all div (for safari on iPad) -webkit-overflow-scrolling: touch;. It works perfectly on the desktop web browser. But I have an effect that I want to change when i launch my webpage on my iPad.
The problem on ipad is : When i use the inertia effect, all div synchronize when the inertia effect is finished. I would like to have the same effect than the desktop web browser, that is, they are synchronized for the effect of inertia and not at the end.
You know, if there is a solution?
To complete my explanation, I created a : JSFiddle
As I know, CSS scrolling inertia on mobile devices cannot be handled with JavaScript. Element scroll event is fired when you scroll it by hand and when animation is finished. During animation no events are fired. So you have to emulate inertia with javascript to sync your divs (and this is not good idea).
I'm working on a web application in which I make widespread use of -webkit-overflow-scrolling:touch.
I'd also be like to be able to implement swipe gestures on those same elements (divs) that utilize this great webkit-specific css feature.
In other words - I'd like this to behave like the Inbox works on the native iOS mail app; if you flick your finger vertically - the inbox scrolls with natural, smooth momentum. If you swipe your finger horizontally - the "mail item" slides to the left or right. Importantly, however, you can't do both - the app only allows to to scroll or swipe.
I assume this is implemented something like this:
Capture the touchstart event, and prevent the default behavior (e.g., event.preventDefault()), because we don't know yet if the user intends to scroll or swipe.
Capture touchmove events, and track how far the user's finger has moved from the initial touch point.
After a certain threshold (e.g., 10 pixels), determine whether the user's finger has moved more vertically or horizontally. If the former - implement scroll. If the later, implement swipe.
In theory - this seems quite doable in JavaScript.
However - I can't get it to work because - once I use event.preventDefault() on the initial touchstart event - I can't subsequently get momentum scrolling to work. That is - I can't find any way to start momentum scrolling programmatically with JavaScript after I've determined that the user intended to scroll.
This seems like it should be a fairly common design pattern (swipe gestures AND webkit-overflow-scrolling:touch), but I haven't been able to find an implementation of it.
I've looked in to hammer.js (http://eightmedia.github.io/hammer.js/); that enables me to detect swipe events on a div that's scrolling.
However - I don't see how that enables me to allow scroll or swipe, but not both. By the time Hammer.js recognizes the swipe gesture - the div is already scrolling.
Thanks in advance!
In my Blackberry Webworks app (for Smartphones OS 6, 7, 7.1), i have some code like this:
<div style="width:100%; height:100%; overflow:hidden;">
<div style="overflow:auto;height:100px;width:100%;">
<ul>
<li>Some</li>
<li>Items</li>
<li>that</li>
<li>needs</li>
<li>the</li>
<li>div</li>
<li>to</li>
<li>be</li>
<li>scrolled</li>
</ul>
</div>
</div>
When trying to scroll the div with a touch gesture i always have to touch the div element once first (like a click) before the scrolling gesture works. So i have to touch it then scroll it, and if i want to scroll again (even if nothing else was touched in between) i have to touch it again and then i can scroll again.
In other words: The touch gesture works every second time i try it (if i dont touch anything else in between).
This behavior is really weird and decreases the usability.
Do you have any idea on how i could change this behavior?
I tried to listen to the touch events (touchstart and touchmove) and scroll the div myself and that works in some way, but you dont have that native scrolling behaviour where it continues scrolling if your gesture was really fast and it also influences the click events somehow (i'm not sure why), but they dont work as good as before.
Try removing the outer container div and change the overflow:auto to overflow:hidden.
I published this page to see how different scrolling behavior can be added to a WebWorks application. It maybe of help to you:
http://blackberry.github.com/WebWorks-Samples/kitchenSink/html/css3/overflow.html
I know for a fact you need to specify a fixed height when using CSS in a WebWorks container. height:100% does not behave as you expect it to (the BrowserField does not auto-expand to be 100% of the screen, but it will expand to be 200px for example).