Puppy
Puppy

Reputation: 146910

Safari not firing touch events

I've got a small jsfiddle - http://jsfiddle.net/qhguktsn/5/. When you tap the text at the top of the link (iOS mobile Safari), you get only the mouse events- no touch events at all, not even on the body. If you tap it on the bottom of the text, you get touch events. We depend on touch events for handling 300ms delay.

How can we get touch events for tapping on the top of the text as well as the bottom?

HTML:

<div style="margin-left:200px;margin-top:200px">
    <a style="vertical-align:center;height: 20px, width: 20px;font-size:100px" href="javascript: void 0">text</a>
</div>

JS:

jQuery("a").on("mousedown", function() { document.body.appendChild(document.createTextNode("mousedown ")); });
jQuery("a").on("mouseup", function() { document.body.appendChild(document.createTextNode("mouseup ")); });
jQuery("a").on("touchstart", function() { document.body.appendChild(document.createTextNode("touchstart ")); });
jQuery("a").on("touchend", function() { document.body.appendChild(document.createTextNode("touchend ")); });
jQuery("a").on("click", function() { document.body.appendChild(document.createTextNode("click ")); });

jQuery(document.body).on("touchstart", function() { document.body.appendChild(document.createTextNode("body touchstart ")); });
jQuery(document.body).on("touchend", function() { document.body.appendChild(document.createTextNode("body touchend ")); });

Upvotes: 17

Views: 38308

Answers (3)

user984003
user984003

Reputation: 29557

I found that the touch event is not fired when clicking on an element contained by a position:fixed element that extends beyond the window. I handled this by making the parent container shorter (used JS to get the exact window height).

This problem was in an app UIWebview using iOS 10. (Yes, still using UIWebview)

Upvotes: 2

Stanimir Dimitrov
Stanimir Dimitrov

Reputation: 1890

This is know bug in Mobile Safari. https://bugs.webkit.org/show_bug.cgi?id=105406 There is another one as well with adding node form different document. https://bugs.webkit.org/show_bug.cgi?id=135628

In order to fix them there are several ways.

  • The first one is to use a small library called fastclick, which supports many mobile devices and OS.

  • The second options is to add event.stopPropagation(); event.preventDefault(); like that. You need both of them.

    jQuery("a").on("mousedown", function(event) {
        event.stopPropagation();
        event.preventDefault();
        document.body.appendChild(document.createTextNode("mousedown ")); 
    });
    
  • The third option is by using the viewport meta tag like that <meta name="viewport" content="width=device-width, user-scalable=no">. This will eliminate all touch delays, without any workarounds. But, again on Safari it may not act like in the other browsers, because hey Safari is the new IE

There is also touch-action, but it's not supported in most of the mobile browsers. :(

Upvotes: 13

Douglas
Douglas

Reputation: 37763

The touch events on the body are due to the body element being shifted down by the margin-top, putting an outline on the body element outlines the touch-target:

body { outline: 1px solid red; }

http://jsfiddle.net/qhguktsn/11/

The second part of the mystery seems to be that the click target expands outside the touch-target:

screenshot of text

Touching the red outline will not trigger a touch event on the body element, but the click event seems to fire when tapped anywhere within the grey -webkit-tap-highlight-color region which expands outside the anchor itself. Taps at the very top will therefore trigger click events on the anchor, but not touch events on the body.

Upvotes: 3

Related Questions