why window doesn't fire click event for touch device - javascript

I have a demo link that I want to add click event for window. It works fine for desktop but not for mobile.
Basically I run tests on lastest Chrome and Safari,
$('#button1').click(function(){
$('#text').append('<div> jquery click</div>')
// this would get executed on both desktop and mobile
})
window.addEventListener('click', function() {
$('#text').append('<div> native click on window</div>')
// this only gets executed on desktop
})
So my question is, why the click event doesn't fire when on mobile?

MDN shows that for Safari, if an element is not considered 'clickable', no click event would fire. I would assume that window is not considered 'clickable' so no 'click' event would fire by window (except the ones propagated by other clickable elements).
There is also a Safari link to explains this.
Though I didn't find anything on Chrome, I would assume since it adopts the same idea.

Apparently Safari doesn't consider the window a clickable event.
As ydydyd pointed out, the Safari docs goes into a more detailed explanation.
To fix it, simply replace window.addEventListener() with document.addEventListener()

Related

Why is touchstart event after click?

Here's something odd, that I felt sure was working in earlier mobile browsers: In Chrome on Android, and Safari on iOS, it seems the touchstart event is fired after the click event, not before. When did this change?
A simple example:
jQuery(function($) {
var touched = false;
$('#clicky').on('touchstart', function(evt){
touched = true;
evt.preventDefault();
})
.click(function(){
if (!touched) {
alert("somehow touch didn't fire")
}
});
})
Run this fiddle, and you'll see the alert can pop up on Android and iOS, when it should actually never show!
http://jsfiddle.net/quxnxu7d/2/
I ran it through Chrome on Android and it worked as you expected for me. I added an alert to the touchstart handler and it fired to be sure that it was firing first and it did.
Take a look at the touch events mdn article. The article specifically mentions:
calling preventDefault() on a touchstart or the first touchmove event of a series prevents the corresponding mouse events from firing
Click is a mouse event so it "should" work as you expect (and it was working for me). I'd verify that the events are indeed running out of order (use console.log() instead of alert()) on your target browsers. If they are, which is perfectly possible with less than perfect browsers/specs, try using a different mouse event like mouseup. My guess is that you'll be able to find an event that works consistently.
Good luck!
Have you tried using mousedown instead of click? That way you should get different events for touch and click without any double firing. You will also likely need to use keydown to keep this site accessible.
There is a 300ms delay between a physical tap and the firing of a click event on some mobile browsers (e.g. iOS Safari)
I ran into the same issue and FastClick jQuery plugin fixed it for me
Have a look FastClick

Android browsers not handling touchmove events correctly

When I try to inspect the touchmove event in this jsbin demo it only triggers once in Chrome and Opera for Android, and immediately after that, it triggers a touchcancel event, instead of continuing to trigger touchmove events?
Based on both the W3C specs, and the behaviour of the touchmove event in both Firefox for Android and Android's default browser, it seems to me that the way the touch events are supposed to work is that the touchmove event keeps triggering while the touch is still on the page. After trying to test in this jsbin though, I got the following log messages:
touchstart event; starting on (140,197) on the screen, or (381,536) on the page.
touchend event; starting on (undefined,undefined) on the screen, or (undefined,undefined) on the page.
touchstart event; starting on (181,137) on the screen, or (492,372) on the page.
touchmove event; starting on (182,153) on the screen, or (495,416) on the page.
touchcancel event; starting on (undefined,undefined) on the screen, or (undefined,undefined) on the page.
This is what happened when I first tapped the screen (shown via a touchstart and touchend), and then dragged the screen (touchstart, touchmove and touchcancel). Going by the same specs mentioned above, the touchcancel event should only run when something interferes , such as the browser interface (if I understand that correctly).
Since I was simply sliding my finger over the body, without leaving the window at all, I am really puzzled by this, so would anybody know why this is happening?
I am getting this unexpected result in Chrome 32 and Opera 19 for Android.
Turns out the problem here was simply the fact the event handler didn't have an event.preventDefault() in it, so the original action still executed, which apparently interrupted the touch event. To fix this, simply add e.preventDefault() in the current event handler function to cancel the current event, and make it work as expected in Chrome and Opera too.
Working demo.

WP8 : IE10 : Differences : Unexpected click through on WP8

I've came across another difference in implementation of IE10 on Windows 8 and Windows Phone 8 (WP8). The first one was related to the IE10 being deaf/blind to keyup event of "enter". Read more here
The other problem I'm facing now is the click event being triggered even if it's not supposed to be triggered. Again, in Windows 8, it works as expected. In WP8, clicking on the top element (link -> here) triggers the onclick event of the element at the bottom, even if they are not nested within each other (both have body element as a parent).
To test,
open the following jsfiddle link in IE10 on your desktop, and click the element 2, the one on top. The expected result is that nothing will happen.
open the same link in IE10 in your WP8 handheld, and click the same element. The onclick event is triggered on element 1, which is not expected.
Could please anyone shed some more light into this for me?
Thank you.
This is really a bizarre behavior. However there is a pretty simple solution for this.
var modal = document.getElementById("elem2");
modal.onclick = function(e) {
return false;
}
Fiddle

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.

HTML Button in iFrame does not work properly on iPad

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!

Categories