16

I made a demo of a photo concept that toggles between two images to show a difference between between them.

I've got an onMouseClick event that works fine, except on the iPad. The response is instant on my desktop, but is quite delayed on the tablet, maybe 500ms?

Is this normal? Is there another way I can handle this?

Javascript:

var img1 = new Image();
img1.src = "http://watkinsfilm.com/wp-content/uploads/2012/09/19mm.jpg";

var img2 = new Image();
img2.src = "http://watkinsfilm.com/wp-content/uploads/2012/09/200mm.jpg";


function test() {
    if (document.pic.src == 'http://watkinsfilm.com/wp-content/uploads/2012/09/19mm.jpg') {

        document.pic.src = 'http://watkinsfilm.com/wp-content/uploads/2012/09/200mm.jpg';
    }
    else if (document.pic.src == 'http://watkinsfilm.com/wp-content/uploads/2012/09/200mm.jpg') {

        document.pic.src = 'http://watkinsfilm.com/wp-content/uploads/2012/09/19mm.jpg';
    }
}​

Body:

 <div>
   <table id="table-1" >
   <tr><td>
      <img id="img" src="http://watkinsfilm.com/wp-content/uploads/2012/09/19mm.jpg" name="pic" onMouseDown="test()"/>
       <img id="png1" src="http://www.thedigitaltrekker.com/wp-content/uploads/2012/03/logo-6smA.png"/>
Click on the image above to toggle between 19mm and 200mm <br>
   </td></tr>
   </table>
</div>
​

Also on jsfiddle: http://jsfiddle.net/ntmw/R4pey/5/

ntmw
  • 177
  • 1
  • 2
  • 7

4 Answers4

16

iOS purposefully delays click events so that gestures/swiping work correctly. For example, when you touch an element you might mean to scroll the whole page, not fire the click event on an element. To achieve finer-grained control, use touch events.

See: https://developer.mozilla.org/en-US/docs/DOM/Touch_events

Example using touchstart: http://jsfiddle.net/R4pey/7/.

Note that capturing touch events has consequences, e.g. you may override a behavior that the user expects (like swiping).

Also note that you should usually bind your events independently of your markup (not inline) to achieve a cleaner separation of markup and script.

Here's an example using jQuery which binds the events separate from the markup, and handles both click and touchstart events. Tested in Chrome 21, FF 15, IE9, and on the iPad 3.

var url1 = "http://watkinsfilm.com/wp-content/uploads/2012/09/19mm.jpg";
var url2 = "http://watkinsfilm.com/wp-content/uploads/2012/09/200mm.jpg";

// preload from original code
var img1 = new Image();
img1.src = url1;

var img2 = new Image();
img2.src = url2;

// bind the click and touchstart events
$("#img").on("click touchstart", function(e){
    if (this.src == url1) {
        this.src = url2;
    }
    else if (this.src == url2) {
        this.src = url1;
    } 

    // When touch event fires, this is needed to prevent the click
    // event from firing as well as @RyanWheale noted in the comments.
    e.preventDefault(); 
});
Tim M.
  • 53,671
  • 14
  • 120
  • 163
  • 1
    This answer is correct, but would like to mention that the simple solution is to use touchstart event. However, be aware that the click event will still fired after roughly 300ms (at least on some devices like Android). If the content beneath the initial touch is replaced with new content, that new content will receive a "click" event. – Ryan Wheale Sep 14 '12 at 01:52
  • Did you see my update? I agree that `touchstart` is most likely the best solution. – Tim M. Sep 14 '12 at 01:53
  • Thank you so much guys. I don't have any experience with jQuery, but Tim's answer makes me comfortable enough to use this method. It's also cleaner than mine, much easier to read :-) – ntmw Sep 14 '12 at 03:08
  • No problem. Note that jQuery isn't *necessary* to make this work, but it makes event binding/handling across browsers much easier (and usually leads to more concise code). – Tim M. Sep 14 '12 at 03:26
  • @TimMedora - Aplogies - as I was scanning, I think I only noticed the "click" in the event binding. I mainly wanted to point out that the "click" event will still fired. So with your solution, you will get a double event fired on some touch devices. – Ryan Wheale Sep 28 '12 at 02:02
  • To prevent double triggers, don't forget to call `event.preventDefault()` in your `touchstart`-listener. This way, you won't get the `onclick` event after 300 ms. – Micros Feb 04 '14 at 08:14
  • Anyone can help me to make it works without jQuery? Using `$(link).on("click touchstart", downKey);` it works. But using `link.addEventListener("touchstart", downKey);link.addEventListener("click", downKey);` doesn't work. In downKey function, I am using `event.preventDefault(); return false;` I added jQuery just to test, but I dont want to use it in this project. – robsonrosa Apr 28 '15 at 21:10
  • @robsonrosa - it's been a few years since I wrote this answer, but I don't think jQuery is doing anything special in this case. What doesn't work? is the delay still present or does the event just not fire? – Tim M. Apr 29 '15 at 00:12
  • Sorry, my explanation was terrible. Without jQuery both events are fired, so I have a mousedown event and touchstart event running. I'd like to prevent on of them if the other was fired before. – robsonrosa Apr 29 '15 at 12:00
  • 1
    Thank you very much @Tim Medora. You saved me! – Ana DEV Mar 01 '17 at 13:31
2

check out the following link for the faster and responsive buttons: https://developers.google.com/mobile/articles/fast_buttons?hl=de-DE&csw=1

amolp1709
  • 204
  • 1
  • 2
  • 10
2

Implement touchend Event Handlers

Unlike click and touchstart, touchend events are fired instantly without a 300ms delay. This may be practical if you’re developing a touch-only WebGL or canvas-based game, however, you cannot rely solely on touchend in standard web pages.

$('#id').on('touchstart',function(e) {                

    //code here...

});
mpalencia
  • 5,481
  • 4
  • 45
  • 59
0

I have experienced some problems with images on IOS devices. For example I use HTML5 gradients and shadows (also images) on my site and noticed a huge response difference when removing the images.

The attached click event is working fine but response is slow because Safari seems to busy with the images (redrawing it constantly).

I used an iPad3 to test it. A guy has written an interesting article about the image problems on IOS.

See: http://roman.tao.at/dev/mobile-safari-memory-usage-with-images/

ntmw
  • 177
  • 1
  • 2
  • 7
Codebeat
  • 6,501
  • 6
  • 57
  • 99
  • @ntmw: Thanks for the grammar fix – Codebeat Sep 14 '12 at 03:26
  • No problem. Thanks for the response. I had no idea iOS devises had such problems. I checked out the article, maybe a bit above me for now, I'll save it for later down the road :-) – ntmw Sep 14 '12 at 03:45