How can I recognize touch events using jQuery in Safari for iPad? Is it possible?
Asked Answered
E

8

204

Is it possible to recognize touch events on the iPad's Safari browser using jQuery?

I used mouseOver and mouseOut events in a web application. Are there any similar events for the iPad's Safari browser since there are no events like mouseOut and mouseMove?

Expressman answered 21/1, 2011 at 4:51 Comment(0)
C
257

Core jQuery doesn't have anything special for touch events, but you can easily build your own using the following events

  • touchstart
  • touchmove
  • touchend
  • touchcancel

For example, the touchmove

document.addEventListener('touchmove', function(e) {
    e.preventDefault();
    var touch = e.touches[0];
    alert(touch.pageX + " - " + touch.pageY);
}, false);

This works in most WebKit based browsers (incl. Android).

Here is some good documentation.

Canticle answered 21/1, 2011 at 5:6 Comment(4)
Thanks a lot David, I think it will work but what is e.touches[0] ? can you describe argument "e" in detail?Expressman
e is the event object that gets automatically passed to the handler. For the safari browser (and android too) it now contains an array of all the touches the user has made on the screen. Each touch has its own properties (x,y coords for example)Canticle
now how do you go about finding what element to trigger event on -__-Averil
Note that the right answer is the one made by Timothy Perez, this one is not updated.Blowzy
S
154

If you're using jQuery 1.7+ it's even simpler than all these other answers.

$('#whatever').on({ 'touchstart' : function(){ /* do something... */ } });
Striker answered 24/3, 2013 at 6:42 Comment(6)
Yes, Timothy, I was not used 1.7+ version at the time I start my project. now onwords I am using jquery 1.7+.. Thanks for good suggestion & reply.. Thanks lot. :)Expressman
This works well. I needed click and touchstart to do the same thing, and I'm used to the non-object syntax, as $('#whatever').on('touchstart click', function(){ /* do something... */ });Pledget
I have used Timothy Perez solution and it works, but not goodeye solution. Is there any way to add also for newly added elements to change code Timothy Perez ?Intercut
when I go $('#whatever').on({ 'touchstart' : function(ev){}});, ev doesn't seem to have any info about the touches (touches, targetTouches or changedTouches)Castellano
@Castellano : You'll find the touches info under ev.originalEvent.Vardon
@Intercut yes, of course. check the docs and look for "delegated events". $("#element to monitor for new elements").on("eventX", "#element", function( event ) {/*whatever*/});Gascony
I
32

Using touchstart or touchend alone is not a good solution, because if you scroll the page, the device detects it as touch or tap too. So, the best way to detect a tap and click event at the same time is to just detect the touch events which are not moving the screen (scrolling). So to do this, just add this code to your application:

$(document).on('touchstart', function() {
    detectTap = true; // Detects all touch events
});
$(document).on('touchmove', function() {
    detectTap = false; // Excludes the scroll events from touch events
});
$(document).on('click touchend', function(event) {
    if (event.type == "click") detectTap = true; // Detects click events
       if (detectTap){
          // Here you can write the function or codes you want to execute on tap

       }
 });

I tested it and it works fine for me on iPad and iPhone. It detects tap and can distinguish tap and touch scroll easily.

Intervenient answered 24/7, 2016 at 8:58 Comment(2)
This solution seems to be the most straight forward I've found and seems to work great on iOS.Cominform
I used jquery mobile first, but then it interfered with other functionalities. I am using this now and works perfect. No issues so far.Zaidazailer
A
24

The simplest approach is to use a multitouch JavaScript library like Hammer.js. Then you can write code like:

canvas
    .hammer({prevent_default: true})
    .bind('doubletap', function(e) { // And double click
        // Zoom-in
    })
    .bind('dragstart', function(e) { // And mousedown
        // Get ready to drag
    })
    .bind('drag', function(e) { // And mousemove when mousedown
        // Pan the image
    })
    .bind('dragend', function(e) { // And mouseup
        // Finish the drag
    });

And you can keep going. It supports tap, double tap, swipe, hold, transform (i.e., pinch) and drag. The touch events also fire when equivalent mouse actions happen, so you don't need to write two sets of event handlers. Oh, and you need the jQuery plugin if you want to be able to write in the jQueryish way as I did.

Armond answered 19/10, 2012 at 10:40 Comment(5)
the "simplest" solution never involves making a problem more complicated by adding librariesCastellano
@Castellano The simplest solution is using hammer.js that abstracts away cross-browser headaches. Use the jQuery extension to be in your familiar zone. Doesn't seem too complicated to me.Moorer
the supposed "simplest" solution is often the one that people screw up the most... whatever you do, don't forget to make sure your solution works on devices that support both touch AND mouse, such as Microsoft SurfaceDischarge
@Octopus: "When all you have is a hammer [sic]... everything looks like a nail" :)Haddad
It's HAMMER TIME! Thank you for sharing this library, it was easy to install on my application and get running! Took a second to setup because the event handler is different, but a simple console.log(event) tells you what you need. THANKS!Shiff
G
21

You can use .on() to capture multiple events and then test for touch on the screen, e.g.:

$('#selector')
.on('touchstart mousedown', function(e){
  e.preventDefault();
  var touch = e.touches[0];
  if(touch){
    // Do some stuff
  }
  else {
    // Do some other stuff
  }
});
Giblet answered 7/10, 2014 at 9:32 Comment(1)
except that .bind is deprecated. You should use .onFiftyfifty
S
15

jQuery Core doesn't have anything special, but you can read on jQuery Mobile Events page about different touch events, which also work on other than iOS devices as well.

They are:

  • tap
  • taphold
  • swipe
  • swipeleft
  • swiperight

Notice also, that during scroll events (based on touch on mobile devices) iOS devices freezes DOM manipulation while scrolling.

Sruti answered 29/11, 2012 at 1:6 Comment(3)
Thanks to give your important time for my question. I looking into Jquery Mobile events.. Thank you.Expressman
Those events aren't truly representative of real touch interaction.Moorer
Is jQuery Core an actual proper noun?Chiffchaff
C
6

I was a little bit worried about using only touchmove for my project, since it only seems to fire when your touch moves from one location to another (and not on the initial touch). So I combined it with touchstart, and this seems to work very well for the initial touch and any movements.

<script>

function doTouch(e) {
    e.preventDefault();
    var touch = e.touches[0];

    document.getElementById("xtext").innerHTML = touch.pageX;
    document.getElementById("ytext").innerHTML = touch.pageY;   
}

document.addEventListener('touchstart', function(e) {doTouch(e);}, false);
document.addEventListener('touchmove', function(e) {doTouch(e);}, false);

</script>

X: <div id="xtext">0</div>
Y: <div id="ytext">0</div>
Cariole answered 25/4, 2012 at 18:53 Comment(1)
I also added this to detect how much time passed since the last event.. document.getElementById("ttime").innerHTML = ((new Date()) - touchTime); touchTime = new Date();Cariole
R
3

I just tested benmajor's GitHub jQuery Touch Events plugin for both 1.4 and 1.7+ versions of jQuery. It is lightweight and works perfectly with both on and bind while providing support for an exhaustive set of touch events.

Rosetterosewall answered 21/2, 2014 at 7:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.