29

I'm looking for the best solution to adding both "doubletap" and "longtap" events for use with jQuery's live(), bind() and trigger(). I rolled my own quick solution, but it's a little buggy. Does anyone have plugins they would recommend, or implentations of their own they'd like to share?

Luke Dennis
  • 14,212
  • 17
  • 56
  • 69

7 Answers7

21

It has been reported to jQuery as a bug, but as doubletapping isn't the same as doubleclicking, it does not have a high priority. However, mastermind Raul Sanchez coded a jquery solution for doubletap which you can probably use! Here's the link, works on mobile Safari.

It's easy to use:

$('selector').doubletap(function() {});

-edit-

And there's a longtap plugin here! You can see a demo on your iPad or iPhone here.

  • 5
    The doubletap plugin doesn't check the position. If you release your finger a different place than where you started, then it shouldn't count as a doubletap. – neoneye Feb 29 '12 at 08:58
  • 1
    that plugin works very bad in case of multitouch gesture on the selector. dont use it – Francesco Apr 27 '12 at 01:32
  • +0 Didn't downvote because technically it works.. That said, it doesn't work _well_ and it doesn't work with `on()` nor `delegate()` etc. It's _something_ but I don't recommend this to anyone. It's best if you can avoid relying on `doubletap`. – Yes Barry Dec 03 '12 at 08:06
  • Any implementation on Android? Thank you! – Alston Dec 17 '12 at 16:33
11

rsplak's answer is good. I checked out that link and it does work well.

However, it only implements a doubletap jQuery function

I needed a custom doubletap event that I could bind/delegate to. i.e.

$('.myelement').bind('doubletap', function(event){
    //...
});

This is more important if you're writing a backbone.js style app, where there is a lot of event binding going on.

So I took Raul Sanchez's work, and turned it into a "jQuery special event".

Have a look here: https://gist.github.com/1652946 Might be useful to someone.

asgeo1
  • 9,028
  • 6
  • 63
  • 85
  • 4
    It's worth noting, that to make this cross platform you have to bind to both `dblclick` and `doubletap`: `$('.myelement').bind('dblclick doubletap', function(event){ /* Stuff */ });` – Nick Q. May 11 '12 at 23:13
6

Just use a multitouch JavaScript library like Hammer.js. Then you can write code like:

canvas
    .hammer({prevent_default: true})
    .bind('doubletap', function(e) { // Also fires on double click
        // Generate a pony
    })
    .bind('hold', function(e) {
        // Generate a unicorn
    });

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.

I wrote a very similar answer to this question because it's also very popular but not very well answered.

Community
  • 1
  • 1
David Johnstone
  • 24,300
  • 14
  • 68
  • 71
6

You can also use jQuery Finger which also supports event delegation:

For longtap:

// direct event
$('selector').on('press', function() { /* handle event */ });

// delegated event
$('ancestor').on('press', 'selector', function() { /* handle event */ });

For double tap:

// direct event
$('selector').on('doubletap', function() { /* handle event */ });

// delegated event
$('ancestor').on('doubletap', 'selector', function() { /* handle event */ });
ngryman
  • 7,112
  • 2
  • 26
  • 23
  • 1
    Based on the hate for the accepted answer, I went with Ngryman's jQuery Finger. It worked perfectly. Thanks man. – Cow Mar 05 '14 at 07:17
  • This is the only solution I could find to work with double clicking on a mobile device with the jeditable jquery plugin. – Keith Oct 15 '14 at 15:46
2

Here's a pretty basic outline of a function you can extend upon for the longtap:

$('#myDiv').mousedown(function() {
    var d = new Date;
    a = d.getTime();
});

$('#myDiv').mouseup(function() {
    var d = new Date;
    b = d.getTime();

    if (b-a > 500) {
        alert('This has been a longtouch!');
    }
});

The length of time can be defined by the if block in the mouseup function. This probably could be beefed up upon a good deal. I have a jsFiddle set up for those who want to play with it.

EDIT: I just realized that this depends on mousedown and mouseup being fired with finger touches. If that isn't the case, then substitute whatever the appropriate method is... I'm not that familiar with mobile development.

eykanal
  • 26,437
  • 19
  • 82
  • 113
0

based on latest jquery docs i've written doubletap event

https://gist.github.com/attenzione/7098476

Attenzione
  • 833
  • 9
  • 12
0
 function itemTapEvent(event) {
    if (event.type == 'touchend') {
        var lastTouch = $(this).data('lastTouch') || {lastTime: 0},
            now       = event.timeStamp,
            delta     = now - lastTouch.lastTime;

            if ( delta > 20 && delta < 250 ) {
                if (lastTouch.timerEv)
                  clearTimeout(lastTouch.timerEv);
                return;
            } else
                $(this).data('lastTouch', {lastTime: now});

            $(this).data('lastTouch')['timerEv'] = setTimeout(function() {
                $(this).trigger('touchend');
            }, 250);
    }
    }

    $('selector').bind('touchend', itemTapEvent);
tdjprog
  • 706
  • 6
  • 11