Long Press in JavaScript?

JavascriptJqueryJquery UiJquery MobileJquery Events

Javascript Problem Overview


Is it possible to implement "long press" in JavaScript (or jQuery)? How?

alt text
(source: androinica.com)

HTML

<a href="" title="">Long press</a>

JavaScript

$("a").mouseup(function(){
  // Clear timeout
  return false;
}).mousedown(function(){
  // Set timeout
  return false; 
});

Javascript Solutions


Solution 1 - Javascript

There is no 'jQuery' magic, just JavaScript timers.

var pressTimer;

$("a").mouseup(function(){
  clearTimeout(pressTimer);
  // Clear timeout
  return false;
}).mousedown(function(){
  // Set timeout
  pressTimer = window.setTimeout(function() { ... Your Code ...},1000);
  return false; 
});

Solution 2 - Javascript

Based on Maycow Moura's answer, I wrote this. It also ensures that the user didn't do a right click, which would trigger a long press and works on mobile devices. DEMO

var node = document.getElementsByTagName("p")[0];
var longpress = false;
var presstimer = null;
var longtarget = null;

var cancel = function(e) {
    if (presstimer !== null) {
        clearTimeout(presstimer);
        presstimer = null;
    }
    
    this.classList.remove("longpress");
};

var click = function(e) {
    if (presstimer !== null) {
        clearTimeout(presstimer);
        presstimer = null;
    }
    
    this.classList.remove("longpress");
    
    if (longpress) {
        return false;
    }
    
    alert("press");
};

var start = function(e) {
    console.log(e);
    
    if (e.type === "click" && e.button !== 0) {
        return;
    }
    
    longpress = false;
    
    this.classList.add("longpress");
    
    if (presstimer === null) {
        presstimer = setTimeout(function() {
            alert("long click");
            longpress = true;
        }, 1000);
    }
    
    return false;
};

node.addEventListener("mousedown", start);
node.addEventListener("touchstart", start);
node.addEventListener("click", click);
node.addEventListener("mouseout", cancel);
node.addEventListener("touchend", cancel);
node.addEventListener("touchleave", cancel);
node.addEventListener("touchcancel", cancel);

You should also include some indicator using CSS animations:

p {
    background: red;
    padding: 100px;
}

.longpress {
    -webkit-animation: 1s longpress;
            animation: 1s longpress;
}

@-webkit-keyframes longpress {
    0%, 20% { background: red; }
    100% { background: yellow; }
}

@keyframes longpress {
    0%, 20% { background: red; }
    100% { background: yellow; }
}

Solution 3 - Javascript

You can use taphold event of jQuery mobile API.

jQuery("a").on("taphold", function( event ) { ... } )

Solution 4 - Javascript

I created long-press-event (0.5k pure JS) to solve this, it adds a long-press event to the DOM.

Listen for a long-press on any element:

// the event bubbles, so you can listen at the root level
document.addEventListener('long-press', function(e) {
  console.log(e.target);
});

Listen for a long-press on a specific element:

// get the element
var el = document.getElementById('idOfElement');

// add a long-press event listener
el.addEventListener('long-press', function(e) {

    // stop the event from bubbling up
    e.preventDefault()

    console.log(e.target);
});

Works in IE9+, Chrome, Firefox, Safari & hybrid mobile apps (Cordova & Ionic on iOS/Android)

Demo

Solution 5 - Javascript

While it does look simple enough to implement on your own with a timeout and a couple of mouse event handlers, it gets a bit more complicated when you consider cases like click-drag-release, supporting both press and long-press on the same element, and working with touch devices like the iPad. I ended up using the longclick jQuery plugin (Github), which takes care of that stuff for me. If you only need to support touchscreen devices like mobile phones, you might also try the jQuery Mobile taphold event.

Solution 6 - Javascript

For modern, mobile browsers:

document.addEventListener('contextmenu', callback);

https://developer.mozilla.org/en-US/docs/Web/Events/contextmenu

Solution 7 - Javascript

jQuery plugin. Just put $(expression).longClick(function() { <your code here> });. Second parameter is hold duration; default timeout is 500 ms.

(function($) {
    $.fn.longClick = function(callback, timeout) {
        var timer;
        timeout = timeout || 500;
        $(this).mousedown(function() {
            timer = setTimeout(function() { callback(); }, timeout);
            return false;
        });
        $(document).mouseup(function() {
            clearTimeout(timer);
            return false;
        });
    };

})(jQuery);

Solution 8 - Javascript

$(document).ready(function () {
    var longpress = false;

    $("button").on('click', function () {
        (longpress) ? alert("Long Press") : alert("Short Press");
    });

    var startTime, endTime;
    $("button").on('mousedown', function () {
        startTime = new Date().getTime();
    });

    $("button").on('mouseup', function () {
        endTime = new Date().getTime();
        longpress = (endTime - startTime < 500) ? false : true;
    });
});

DEMO

Solution 9 - Javascript

For cross platform developers (Note All answers given so far will not work on iOS):

Mouseup/down seemed to work okay on android - but not all devices ie (samsung tab4). Did not work at all on iOS.

Further research its seems that this is due to the element having selection and the native magnification interupts the listener.

This event listener enables a thumbnail image to be opened in a bootstrap modal, if the user holds the image for 500ms.

It uses a responsive image class therefore showing a larger version of the image. This piece of code has been fully tested upon (iPad/Tab4/TabA/Galaxy4):

var pressTimer;  
$(".thumbnail").on('touchend', function (e) {
   clearTimeout(pressTimer);
}).on('touchstart', function (e) {
   var target = $(e.currentTarget);
   var imagePath = target.find('img').attr('src');
   var title = target.find('.myCaption:visible').first().text();
   $('#dds-modal-title').text(title);
   $('#dds-modal-img').attr('src', imagePath);
   // Set timeout
   pressTimer = window.setTimeout(function () {
      $('#dds-modal').modal('show');
   }, 500)
});

Solution 10 - Javascript

The Diodeus's answer is awesome, but it prevent you to add a onClick function, it'll never run hold function if you put an onclick. And the Razzak's answer is almost perfect, but it run hold function only on mouseup, and generally, the function runs even if user keep holding.

So, I joined both, and made this:

$(element).on('click', function () {
    if(longpress) { // if detect hold, stop onclick function
        return false;
    };
});

$(element).on('mousedown', function () {
    longpress = false; //longpress is false initially
    pressTimer = window.setTimeout(function(){
    // your code here

    longpress = true; //if run hold function, longpress is true
    },1000)
});

$(element).on('mouseup', function () {
    clearTimeout(pressTimer); //clear time on mouseup
});

Solution 11 - Javascript

You could set the timeout for that element on mouse down and clear it on mouse up:

$("a").mousedown(function() {
    // set timeout for this element
    var timeout = window.setTimeout(function() { /* … */ }, 1234);
    $(this).mouseup(function() {
        // clear timeout for this element
        window.clearTimeout(timeout);
        // reset mouse up event handler
        $(this).unbind("mouseup");
        return false;
    });
    return false;
});

With this each element gets its own timeout.

Solution 12 - Javascript

You can use jquery-mobile's taphold. Include the jquery-mobile.js and the following code will work fine

$(document).on("pagecreate","#pagename",function(){
  $("p").on("taphold",function(){
   $(this).hide(); //your code
  });    
});

Solution 13 - Javascript

Most elegant and clean is a jQuery plugin: https://github.com/untill/jquery.longclick/, also available as packacke: https://www.npmjs.com/package/jquery.longclick.

In short, you use it like so:

$( 'button').mayTriggerLongClicks().on( 'longClick', function() { your code here } );

The advantage of this plugin is that, in contrast to some of the other answers here, click events are still possible. Note also that a long click occurs, just like a long tap on a device, before mouseup. So, that's a feature.

Solution 14 - Javascript

I needed something for longpress keyboard events, so I wrote this.

var longpressKeys = [13];
var longpressTimeout = 1500;
var longpressActive = false;
var longpressFunc = null;

document.addEventListener('keydown', function(e) {
	if (longpressFunc == null && longpressKeys.indexOf(e.keyCode) > -1) {
		longpressFunc = setTimeout(function() {
			console.log('longpress triggered');
			longpressActive = true;
		}, longpressTimeout);
		
	// any key not defined as a longpress
	} else if (longpressKeys.indexOf(e.keyCode) == -1) {
		console.log('shortpress triggered');
	}
});

document.addEventListener('keyup', function(e) {
	clearTimeout(longpressFunc);
	longpressFunc = null;
	
	// longpress key triggered as a shortpress
	if (!longpressActive && longpressKeys.indexOf(e.keyCode) > -1) {
		console.log('shortpress triggered');
	}
	longpressActive = false;
});

Solution 15 - Javascript

This worked for me:

const a = document.querySelector('a');

a.oncontextmenu = function() {
   console.log('south north');
};

https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/oncontextmenu

Solution 16 - Javascript

In vanila JS if need to detect long-click after click released:

    document.addEventListener("mousedown", longClickHandler, true);
    document.addEventListener("mouseup", longClickHandler, true);

    let startClick = 0;
    function longClickHandler(e){   
      if(e.type == "mousedown"){
        startClick = e.timeStamp;
      }
      else if(e.type == "mouseup" && startClick > 0){
        if(e.timeStamp - startClick > 500){  // 0.5 secound
          console.log("Long click !!!");
        }
      }
    }

May need to use timer if need to check long-click while clicking. But for most case after release click is enought.

Solution 17 - Javascript

For me it's work with that code (with jQuery):

var int       = null,
    fired     = false;
    
var longclickFilm = function($t) {
        $body.css('background', 'red');
    },
    clickFilm = function($t) {
        $t  = $t.clone(false, false);
        var $to = $('footer > div:first');
        $to.find('.empty').remove();
        $t.appendTo($to);
    },
    touchStartFilm = function(event) {
        event.preventDefault();
        fired     = false;
        int       = setTimeout(function($t) {
            longclickFilm($t);
            fired = true;
        }, 2000, $(this)); // 2 sec for long click ?
        return false;
    },
    touchEndFilm = function(event) {
        event.preventDefault();
        clearTimeout(int);
        if (fired) return false;
        else  clickFilm($(this));
        return false;
    };

$('ul#thelist .thumbBox')
    .live('mousedown touchstart', touchStartFilm)
    .live('mouseup touchend touchcancel', touchEndFilm);

Solution 18 - Javascript

You can check the time to identify Click or Long Press [jQuery]

function AddButtonEventListener() {
try {
    var mousedowntime;
    var presstime;
    $("button[id$='" + buttonID + "']").mousedown(function() {
        var d = new Date();
        mousedowntime = d.getTime();
    });
    $("button[id$='" + buttonID + "']").mouseup(function() {
        var d = new Date();
        presstime = d.getTime() - mousedowntime;
        if (presstime > 999/*You can decide the time*/) {
            //Do_Action_Long_Press_Event();
        }
        else {
            //Do_Action_Click_Event();
        }
    });
}
catch (err) {
    alert(err.message);
}
} 

Solution 19 - Javascript

like this?

target.addEeventListener("touchstart", function(){
   // your code ...
}, false);    

Solution 20 - Javascript

You can use jquery Touch events. (see here)

  let holdBtn = $('#holdBtn')
  let holdDuration = 1000
  let holdTimer

  holdBtn.on('touchend', function () {
    // finish hold
  });
  holdBtn.on('touchstart', function () {
    // start hold
    holdTimer = setTimeout(function() {
      //action after certain time of hold
    }, holdDuration );
  });

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRandy MayerView Question on Stackoverflow
Solution 1 - JavascriptDiodeus - James MacFarlaneView Answer on Stackoverflow
Solution 2 - JavascriptkelunikView Answer on Stackoverflow
Solution 3 - JavascriptdoganakView Answer on Stackoverflow
Solution 4 - JavascriptJohn DohertyView Answer on Stackoverflow
Solution 5 - JavascriptʇsәɹoɈView Answer on Stackoverflow
Solution 6 - JavascriptKory NunnView Answer on Stackoverflow
Solution 7 - Javascriptpiwko28View Answer on Stackoverflow
Solution 8 - JavascriptrazzView Answer on Stackoverflow
Solution 9 - Javascripttyler_mitchellView Answer on Stackoverflow
Solution 10 - JavascriptMaycow MouraView Answer on Stackoverflow
Solution 11 - JavascriptGumboView Answer on Stackoverflow
Solution 12 - JavascriptPrashant_MView Answer on Stackoverflow
Solution 13 - JavascriptuntillView Answer on Stackoverflow
Solution 14 - JavascriptBrad.SmithView Answer on Stackoverflow
Solution 15 - JavascriptZomboView Answer on Stackoverflow
Solution 16 - JavascriptZorroView Answer on Stackoverflow
Solution 17 - JavascriptmolokolocoView Answer on Stackoverflow
Solution 18 - JavascriptDerinView Answer on Stackoverflow
Solution 19 - Javascript翁沈顺View Answer on Stackoverflow
Solution 20 - JavascriptIrteza AsadView Answer on Stackoverflow