Sweet Skills #1 - Handling long-press events with jQuery

This will be a quick one, I promise ...

E don tey (It's been forever) since I read a post on jQuery. Everyone seems to be hush-hush about it and focused on the new trendy kids on the block.

New kids on the block

So which of these is Angular, yea? The one with the 45° jawline? 😜

But jQuery is cool and still has lots of surprises if you just care to look.

This article, for instance, will show us to handle long-press events for html elements with simple jQuery code.

Long-press

Press it ... harder 🤷

Our goals

  • It should be easy to understand.
  • Previously set click events for our long-press element should only be handled if press-time is less than 1000 ms

Get it?

Let's get coding ...

Goal #1

I got the idea for handling basic long-press events from this StackOverflow answer. Really impressive.

//here is a minor refactor of it
var pressTimer;  
$("a").mouseup(function(){
  clearTimeout(pressTimer);
  return false;
}).mousedown(function(){
  pressTimer = window.setTimeout(function() {
    console.log("long-press event handled");
  },1000);
  return false; 
});

So,

  • we declare a variable pressTimer
  • to hold a reference to our window.setTimeout instance
  • which is set to execute after 1000 milliseconds or 1 second
  • after the mousedown event is triggered
  • If the mouseup event is triggered before then (1000 ms), the setTimeout is cancelled or cleared

This is pretty basic and we can see it in this JS Fiddle

If you still have questions about this, you can ask in the comments section.

Goal #2

If we had a click handler on that button to do say console.log("click event handled"), yea?

Would that still execute on the long-press event?

This Fiddle says YES!

But we only want the "click event handled" text to be logged if the press-time is less than 1000 ms.

So we need to calculate that, huh?

This Fiddle logs the press-time to the console.

Now based on that press-time (I really should stop using this word), we can choose whether to handle click events or long-press events.

How do we do that?

JQuery gives us a way to get all events registered for an element with its jQuery._data API. It's an awesome feature.

With this, we can:

  • get all click event listeners registered for the element in an array,
  • store them in a variable,
  • remove the click event listeners from the element,
  • choose between handling click and long-press based on the press-time

This Fiddle shows us how to do just that.

Final Code:

$("a").click(function () { //adds an event listener
   console.log("click event handled");
})

var pressTimer; //a reference to our setTimeout listener  
var d; //to contain the datetime mousedown instance  
var clickEvents = $._data($("a").get(0), "events").click.slice(0); //contains all prior click event listeners on the element  
$("a").mouseup(function(){
  clearTimeout(pressTimer);
  if (((new Date()) - d) > 1000) {
    //long-press
  }
  else {
      var self = this;
    clickEvents.forEach(function (ev) {
      ev.handler.call($(self)[0]);
    });
  }
  return false;
}).mousedown(function(){
    d = new Date();
  pressTimer = window.setTimeout(function() {
    console.log("long-press event handled");
  },1000);
  return false; 
});
$("a").off("click");

If you have any questions, please ask in the comments section.

Show Comments