0

In order to implement a "long press" on mobile, I started with a simple event map where touchstart sets a time, touchend sets another and then calculates the difference to see how long the element was pressed. This was my old code:

        $('html')
            .on({
                touchstart : function(e){
                    g.tt.start = new Date();
                },
                touchend : function(e){
                    g.tt.end = new Date();
                    g.tt.delta = g.tt.end - g.tt.start;
                    alert(g.tt.delta);
                    g.tt = {};
                }
            })
        ;

but unfortunately...

...every other press kept calculating the difference from the previous touchend to the touchstart. I'm pretty sure there is something basic I'm missing and thus end up over-engineering this (no formal training I'm afraid). Here is my new code:

        $('html')
            .on({
                touchstart : function(e){
                    g.tt = {};
                    g.tt.start = new Date();
                },
                touchend : function(e){
                    g.tt.end = new Date();
                    g.tt.delta = g.tt.end - g.tt.start;
                    if( isNaN(g.tt.delta) == false ) {
                        alert(g.tt.delta);
                    } 
                    else {
                        return false;
                    }
                    setTimeout(function(){g.tt = {}; });
                }
            })
        ;

Shouldn't there be a much easier way to do this with less clauses? Never mind my funny g.tt variable names.

tim
  • 3,823
  • 5
  • 34
  • 39

2 Answers2

1

I'm realizing that I took the wrong approach, and also found a nice plugin:

http://aanandprasad.com/articles/jquery-tappable/

tim
  • 3,823
  • 5
  • 34
  • 39
0

You are timing the difference between two events, so there is no need to use setTimeout, just use closure to share some variables between the two events. This example is taken from this answer:

(function () {
  var start, end;
  $('html').on({
    touchstart : function(e){
      start = +new Date(); // get unix-timestamp in milliseconds
    },
    touchend : function(e){
      end = +new Date();
      g.tt.delta = end - start;
      if( isNaN(g.tt.delta) == false ) {
        alert(g.tt.delta);
      }
    }
  });
})();

Here is a demo showing this with mouse events and touch events

Community
  • 1
  • 1
Jason Sperske
  • 29,816
  • 8
  • 73
  • 124
  • See, but like my original code, your solution also causes the second tap to be calculated. For some reason it only works on ever OTHER touch. – tim Sep 25 '12 at 23:28
  • why do you have a + in front of the new Date()? – tim Sep 25 '12 at 23:34
  • From a comment on the linked answer, "It just does type-conversion (to Number), see the following answer for more details: http://stackoverflow.com/questions/1983040/what-does-the-new-mean-in-javascript/1983109#1983109" I found that approach rather elegant. Also I've create a touch based demo and tested it on my ipad, seems to work for me – Jason Sperske Sep 25 '12 at 23:36