Scroll event fire delay in mobile - javascript

I got event listener to the scroll and everything works fine with desktop browsers(when scrolling starts - the event fired straight away) and chrome browser in mobile(chrome latest version + android version 5.0), but with other mobile browsers(ff, android browser) this works differently, and after googling for some I found the reason: it's because the scroll event is not fired until the scrolling action comes to a complete stop(releasing the finger from the screen).
My question is there some workaround for this, perhaps some best practice, so it will fire normally(as for desktop) and without dramatically performance changes?
*JS solution only(no for jquery).

You can use iScroll. It does not depend on jQuery and achieves what you want ( firing scroll events on mobile platforms ~continuously ) among other things.
You can refer to this answer for how to implement this using iScroll.

I agree the answer of Mohit Bhardwaj and I just want to say some important thing about iScroll.
The iScroll runs depend on css3 translate and the js event such as touchMove, touchStart and touchEnd. You can just think it handle the whole scroll system in your page or the element container you set it to handle.
One thing you should know, if you want to listen the scroll event in iScroll, you must import the iscroll-probe.js, and set the probeType param with 2 or 3. Otherwise you would not get the scroll event.
The iScroll version 5 is good, I use it in a lot of project. You can see it docs and code
here

Related

Using <a href""> instead of click/touch/pointer event

I've been struggling for a while making websites compatible for desktop, tablet and mobile at once. There are loads of libraries to handle pointer events on touch devices. One of them is hand.js, which combines mouse and touch in pointer events, without me having to consider what device it is used for. Hand.js is working superb, exept for one problem. On touch devices, a pointerdown event is triggered even if it is intended as the start of a scroll or pinch.
There are solutions to work around this, but instead of adding more and more javascript, I considered ditching all libraries for touch and let the browser decide for itself.
To accomplish this, I'm thinking of using (or abusing :-) the <a href""> tag.
Instead of (for simplicity I use onclick inline instead of add an eventlistener) using:
<div class="myclass" onclick="start(1,2,3)">Hello</div>
I could use
Hello</div>
The benefit of this solution would be:
the device browser decides how to handle the click/touch, whilst zooming and scrolling is still enabled without triggering any unwanted action.
there is no need to register any event to the button.
I don't need any library
I've created a fiddle and (to my surprise) it is working. However, I'm no expert, hence my question:
Can I use this method without running into problems?

window.onscroll mobile equivalent?

On desktop browsers, window.scroll fires off continuously as the browser is scrolled. However, in my testing on iOS and Android Chrome, it only fires when the scrolling has finished.
I tried touchmove but that had the same behavior - only firing when the movement finished.
Is there an event on mobile devices that fires continuously, like a desktop browser?
Apparently there's no way to get passed it because the "iOS devices freeze the DOM manipulation during the scroll event"!
Take a look at this link the scroll start section! http://demos.jquerymobile.com/1.0/docs/api/events.html
Might want to take a look at this site:
http://andyshora.com/mobile-scroll-event-problems.html
It helps explains why your going to be banging you head against a wall.

How to effectively prevent document scrolling in android?

I have a website where I'd like to implement drag-and-drop in both desktop and mobile. I was able to do it in the desktop, and the mobile interface works as well, as long as the document doesn't scroll. Unfortunately, I haven't found a consistent way to prevent the document from scrolling in mobile browsers.
Here is what I have so far:
On the iPhone, I can preventDefault on either touchstart or touchmove. This lets me handle the touchmove event before calling preventDefault and canceling the document scroll.
On the Android, I must prevent touchstart!
Unfortunately, however, if I prevent touchstart, I don't get any more touchmove events! So are there any better ways to do it? Perhaps making everything position: fixed on the fly when someone does touchstart?
I would have been happy to overflow: auto, but unfortunately I think that only works in Android 4, i.e. tons of Android users won't be able to use it. Meanwhile, iScroll and other solutions seem to be kind of slow and -- worse yet -- don't really prevent the document scrolling either. Is this still the case?
In short, what to do?

Disable the firing of touchcancel in Android Browser

I am making a mobile website that uses JavaScript touch events. Things work fine in iOS Safari and Chrome for Android, but the stock Android Browser (version 4.1.2) is giving me trouble.
During a touch process, the touchstart and touchmove events are called as expected. However, one of the actions performed by the touchmove handler seems to trigger a premature touchcancel event. (I'm not sure whether this is significant, but the action that triggers the touchcancel is the modification of an SVG object's viewBox attribute.) If I comment out this action, the touch process proceeds normally (i.e., completion of touchmove through to touchend).
All of my touch handlers call the preventDefault() function, so the issue isn't the one that's described in this bug: https://code.google.com/p/android/issues/detail?id=19827.
I've read that there is a lot of inconsistency among browsers as to when touchcancel is called. The stock Android browser is the only one that is problematic for me.
Is there a workaround out there? For example, is there away I can completely disable the touchcancel event? Another idea I had was to have the touchcancel handler programmatically trigger another touchstart/touchmove event, but I didn't get very far with that. Any ideas would be appreciated.
I know it's a bit late but if someonee else is facing this issue, here's a small jQuery extension that explains how to deal with pointercancel and touchcancel events.
Basically, if you switch to pointer events you will be able to prevent pointercancel by simply using the touch-action CSS property with a value of none, as long as the browser has both features correctly implemented. (Android 5+, Chrome 55+, IE11, Edge, etc)
If you really must use the legacy touch events instead, you'll have to implement event.preventDefault() in your touchmove events and this will prevent touchcancel from firing, but it will also disable entirely the browser handling of any default action like a pan or click.
As a final note, I wouldn't use touch events + touch-action CSS rules because touch-action was only recently added, at the same that that Pointer Events. So while that combination may work in newer browsers, it will most certainly fail in older ones (by triggering touchcancel event unexpectedly).
Check the README from the jQuery extension I posted because it explains the implications of using either TouchEvent and PointerEvent interfaces.
If you are useing hammer.js, you can disable pointer-events (which cause problems like this), by adding:
delete window.PointerEvent;
in your index.html PRIOR to loading hammer.js, and it will ignore those events.
You can also set SUPPORT_POINTER_EVENTS = false; (line 384 of v2.0.8) to do the same thing.
Ideally the devs would add the ability to turn this off, but so goes the open source dilemma...
I think touchcansel is special event that triggers when user touched button in specific behavior.
Ex. User touch button, but didn't removed his finger from display on exactly that button, instead of this he could move it a bit to the left, and end his action there. In that case touchcancel would appear.
So if you don't want that action to fire, i think you have to remove all handlers that connected with that action in android browser.
$('selector').off('touchcancel'), of if it's delefated $('parent').undelegate('touchcancel','selector')
I don't think that there is problem with e.preventDefault(). Only may be if you click on a link, and page starts to reload. May be page is reloaded when you click on button? and you wait for some actions after page reloaded, you actually may not understand, that it happend.

bypassing mouseover events for iOS

Our website makes use of the overLIB library to show "more information" about clickable links on mouseover. The result is that on iOS devices, the first click will result in the mouseover text appearing, while the second will activate the link.
What is the easiest way to keep the mouseover text for non-iOS browsers, while bypassing it for users using iOS, so that for iOS, the links are activated on the first click?
If you want an easy solution, you can use something like Modernizr as described here: What's the best way to detect a 'touch screen' device using JavaScript?. Then, you can bind your overLIB events to the non-touch classes, etc. This way, you can address all touch device users and not just iOS users. Of course, if you want just iOS users, you can always UA sniff ( http://www.quirksmode.org/js/detect.html ), though its not recommended.
However, you then still have the problem that you're loading the overLIB script(s) for users who don't need it. I think the best way to avoid this depends on the rest of your stack.
Another thing to think about is the purpose of the hover tips. If they are useful on your desktop site for helping users to learn about where they're going without making the investment of a click, why aren't they useful on your touch device site? I know that hover is clunky on touch devices, but I think they're common enough since there's no alternative yet. I'd bet that touch device users understand the flow. The only example that comes to mind is Seamless.com - when you select a menu item from a restaurant, you get a "hover" description and then it requires a second click to select the item.
I realize that this is an old question - answering for the Googlers. :)
Another solution is to use .mousemove() instead of .mouseover().
iOS ignores the .mousemove() event and triggers a click on the first touch.

Categories