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?
Related
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
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?
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.
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.
I have a web application in which I have a div element with an onclick javascript action. This web application works fine on iPads and desktops alike.
When it is launched within an iFrame on an iPad, however, all of the sudden, my clicks/taps are rarely and inconsistently acted upon. When running in an iFrame on a desktop browser, I do not see this behavior.
Has anyone seen this type of behavior before?
I'm not sure about your exact situation, but I was having a similar problem when my botton had a "mouseenter" event trigger binded to it. The mouse enter would be called on the first "tap" and the button would be called on the "second". Because of the way ipad uses those two events.
My solution was to use the browser detection tool from http://detectmobilebrowsers.com/ and set a var ismolible = to true or false, depending on whether the browser was mobile or not, then I used an if statement to unbind my mouseenter immediately if the browser was mobile. You do have to modify the http://detectmobilebrowsers.com/ code for ipad.
Hope this helps!