Blackberry Webworks: Weird scrolling behavior with touchscreens - javascript

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).

Related

iOS Webkit detect swipe and drag events on scrolling element with Javascript

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.

Problems with .scroll function in mobile browsers

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.

ng-view will not auto hide address/navigation bar on mobile devices

I am building a mobile website using Mobile Angular UI. After almost completion I tried to finally test it on my mobile devices. I realized that: when I scroll down the page, the navigation bar of the browser(i.e. Safari on iPhone, Chrome on Android devices) does not auto hide like it used to function when browsing normal websites.
Such as these website:
Mobile Angular UI Demo (My project's index.html is almost identical to this index.html)
wReader
Is there fix? Or is just a disadvantage of ng-view and I am going to have to deal with it?
Any outputs are greatly appreciated. Thanks in advance.
This cannot be solved, unfortunately, unless you want to use a different theme or make your own.
This is caused by the CSS. By default, scrolling in Mobile Safari doesn't feel native—the page scrolls more slowly compared to native apps.
In order to get smoother, bouncy, native-feeling iOS scrolling, a parent element (either a div or body) with a height of 100% of the window height is used and it has an overflow-y: scroll property.
Also, some of your theme's features (like the slide-out nav) may require this CSS implementation to work properly.
When scrolling, you are scrolling inside of that element—you are not scrolling the page. Mobile Safari will shrink the address bar when the page scrolls but when this CSS is added, it is detecting that the page does not need to scroll (because the parent element of all of the elements is 100% the height of the window and does not exceed that). This means that the page isn't scrolling and instead a child element on the page has content that is scrolling), Mobile Safari does not detect page scrolling. This cannot be changed. I have a similar implementation on my website.
I made a CodePen that shows how this effect is made. Due to the body (grey) not needing to scroll—because it is 500px tall which is less than the window height—the scrolling happens in one of the elements that allows scrolling. Mobile Safari doesn't know that you want this parent element to act like the whole page so unfortunately this can't be fixed. In the above pen, the blue element is the parent element that simulates the whole page. The child elements are just there to add height/scrollable content.

Remove 'bouncy scrolling' on mobile devices

I'm trying to find a way to get rid of the bouncy scrolling behaviour on mobile devices (e.g. when there is no content below to scroll yet you are still able to do it and scroll content to top and when released it bounces back)
My html structure looks like this
<html>
<body>
<div id="wrapper">
<div id="container">
where all elements stretch to full height of the window. I tried overflow hidden on html and body, auto etc.. yet nothing seems to achieve a state where if you scroll than it doesn't scroll unless there is more content below.
It sounds like what you're looking for is to disable the scroll bounce for a UIWebView in iOS. If you're developing a native iOS app, you can disable the bounce by setting [WebViewObject].bounces = NO where [WebViewObject] is the UIWebView.
If you're just looking to prevent the bounce in the Safari mobile browser, I don't believe there's a way to do this.

Scroll event on Android Browser not firing. Need workaround

I've created a website with a parallax street scene. See here for an archived version.
It works just fine on all major desktop browsers, and Safari Mobile. It works fine in Mobile Firefox and Chrome for Android Beta also. However the default Android browser has issues with the scroll event. Let me be clear. Scrolling is not the issue. The div scrolls as required. The scroll event doesn't fire. This issue I experience on Honeycomb as well as ICS.
I'm not concerned about other mobile browsers because for mobile screen sizes one usually does not see the parallax scene; mediaqueries and conditional JavaScript loading take care of that. Responsive design and all that jazz.
Basically, I've written a parallise() jQuery plugin that positions each image based on its position and 'depth'. This function is bound to the scroll event.
On Android Browser, this event only fires at the start of the next touch, instead of continuously.
OK, so I thought that perhaps if I bound the function to touchstart, touchmove, and touchend events I would solve my issue. No cigar. Other touch events are also bugged. Applying the suggested workaround causes the events to fire, but as I have to e.preventDefault(), scrolling (the whole point of the exercise) is disabled.
What if I just poll the position of the stage div relative to the window div? Turns out that the position information is only updated at the start of the next touch.
I am at the end of my tether. Any help would be much appreciated.
Even if the touch events worked correctly on the bugged versions of Android, and you were then effectively able to track the native scroll position during a drag, this would be prone to error. For example, it wouldn't account for the momentum animation which happens after the touching has finished.
iOS and Android make sacrifices to improve the performance of scrolling. On both platforms, it's not possible to get the accurate scroll position until the scroll has completed. The scroll event (on the <body>) doesn't fire until the momentum animation is finished. So while your original question is about scroll events on an overflowing <div>, fixing this might not be totally helpful for you anyway.
If you want an animation to update in time with the scroll, then you need to perform the scroll programatically rather than using the browser's native scroll. The best library to do this is iScroll. You can achieve parallax effects very easily as seen in this demo.
If you need more complex effects (the walking character, in your example), you can opt for the "probe" version of iScroll which allows pixel-perfect polling of scroll position in return for reduced performance.
However, there are many downsides to using iScroll:
You may need to change your markup and styling
It is unnecessary overhead for desktop browsers, but due to markup changes may be difficult to use only as a fallback
The scrolling will not feel perfect - on iOS, with its usually excellent scrolling performance - the slight difference in momentum calculation can feel jarring. On Android, the scrolling can become more laggy than usual.
Swipe shim that doesn't need preventdefault on touchstart: https://github.com/TNT-RoX/android-swipe-shim

Categories