[javascript] Long Press in JavaScript?

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; 
});

This question is related to javascript jquery jquery-ui jquery-mobile jquery-events

The answer is


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
  });    
});

I created long-press-event (0.5k pure JavaScript) 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


You can use taphold event of jQuery mobile API.

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

I think This can help you :

_x000D_
_x000D_
var image_save_msg = 'You Can Not Save images!';_x000D_
var no_menu_msg = 'Context Menu disabled!';_x000D_
var smessage = "Content is protected !!";_x000D_
_x000D_
function disableEnterKey(e) {_x000D_
    if (e.ctrlKey) {_x000D_
        var key;_x000D_
        if (window.event)_x000D_
            key = window.event.keyCode; //IE_x000D_
        else_x000D_
            key = e.which; //firefox (97)_x000D_
        //if (key != 17) alert(key);_x000D_
        if (key == 97 || key == 65 || key == 67 || key == 99 || key == 88 || key == 120 || key == 26 || key == 85 || key == 86 || key == 83 || key == 43) {_x000D_
            show_wpcp_message('You are not allowed to copy content or view source');_x000D_
            return false;_x000D_
        } else_x000D_
            return true;_x000D_
    }_x000D_
}_x000D_
_x000D_
function disable_copy(e) {_x000D_
    var elemtype = e.target.nodeName;_x000D_
    var isSafari = /Safari/.test(navigator.userAgent) && /Apple Computer/.test(navigator.vendor);_x000D_
    elemtype = elemtype.toUpperCase();_x000D_
    var checker_IMG = '';_x000D_
    if (elemtype == "IMG" && checker_IMG == 'checked' && e.detail >= 2) {_x000D_
        show_wpcp_message(alertMsg_IMG);_x000D_
        return false;_x000D_
    }_x000D_
    if (elemtype != "TEXT" && elemtype != "TEXTAREA" && elemtype != "INPUT" && elemtype != "PASSWORD" && elemtype != "SELECT" && elemtype != "OPTION" && elemtype != "EMBED") {_x000D_
        if (smessage !== "" && e.detail == 2)_x000D_
            show_wpcp_message(smessage);_x000D_
_x000D_
        if (isSafari)_x000D_
            return true;_x000D_
        else_x000D_
            return false;_x000D_
    }_x000D_
}_x000D_
_x000D_
function disable_copy_ie() {_x000D_
    var elemtype = window.event.srcElement.nodeName;_x000D_
    elemtype = elemtype.toUpperCase();_x000D_
    if (elemtype == "IMG") {_x000D_
        show_wpcp_message(alertMsg_IMG);_x000D_
        return false;_x000D_
    }_x000D_
    if (elemtype != "TEXT" && elemtype != "TEXTAREA" && elemtype != "INPUT" && elemtype != "PASSWORD" && elemtype != "SELECT" && elemtype != "OPTION" && elemtype != "EMBED") {_x000D_
        //alert(navigator.userAgent.indexOf('MSIE'));_x000D_
        //if (smessage !== "") show_wpcp_message(smessage);_x000D_
        return false;_x000D_
    }_x000D_
}_x000D_
_x000D_
function reEnable() {_x000D_
    return true;_x000D_
}_x000D_
document.onkeydown = disableEnterKey;_x000D_
document.onselectstart = disable_copy_ie;_x000D_
if (navigator.userAgent.indexOf('MSIE') == -1) {_x000D_
    document.onmousedown = disable_copy;_x000D_
    document.onclick = reEnable;_x000D_
}_x000D_
_x000D_
function disableSelection(target) {_x000D_
    //For IE This code will work_x000D_
    if (typeof target.onselectstart != "undefined")_x000D_
        target.onselectstart = disable_copy_ie;_x000D_
_x000D_
    //For Firefox This code will work_x000D_
    else if (typeof target.style.MozUserSelect != "undefined") {_x000D_
        target.style.MozUserSelect = "none";_x000D_
    }_x000D_
_x000D_
    //All other  (ie: Opera) This code will work_x000D_
    else_x000D_
        target.onmousedown = function() {_x000D_
            return false_x000D_
        }_x000D_
    target.style.cursor = "default";_x000D_
}_x000D_
// on_body_load_x000D_
_x000D_
window.onload = function() {_x000D_
    disableSelection(document.body);_x000D_
};_x000D_
_x000D_
_x000D_
_x000D_
// disable_Right_Click_x000D_
_x000D_
_x000D_
_x000D_
document.ondragstart = function() {_x000D_
    return false;_x000D_
}_x000D_
_x000D_
function nocontext(e) {_x000D_
    return false;_x000D_
}_x000D_
document.oncontextmenu = nocontext;
_x000D_
_x000D_
_x000D_


like this?

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

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);
}
} 

For modern, mobile browsers:

document.addEventListener('contextmenu', callback);

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


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.


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;
});

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.


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.


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);

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 );
  });

$(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


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
});

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; }
}

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)
});

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);

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to jquery

How to make a variable accessible outside a function? Jquery assiging class to th in a table Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Getting all files in directory with ajax Bootstrap 4 multiselect dropdown Cross-Origin Read Blocking (CORB) bootstrap 4 file input doesn't show the file name Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource how to remove json object key and value.?

Examples related to jquery-ui

How to auto adjust the div size for all mobile / tablet display formats? jQuery not working with IE 11 JavaScript Uncaught ReferenceError: jQuery is not defined; Uncaught ReferenceError: $ is not defined Best Practice to Organize Javascript Library & CSS Folder Structure Change table header color using bootstrap How to get HTML 5 input type="date" working in Firefox and/or IE 10 Form Submit jQuery does not work Disable future dates after today in Jquery Ui Datepicker How to Set Active Tab in jQuery Ui How to use source: function()... and AJAX in JQuery UI autocomplete

Examples related to jquery-mobile

How to auto adjust the div size for all mobile / tablet display formats? how to get value of selected item in autocomplete jQuery Cross Domain Ajax How to set cookie value with AJAX request? Disable scrolling when touch moving certain element disable past dates on datepicker Custom Input[type="submit"] style not working with jquerymobile button jQuery Mobile: document ready vs. page events How to redirect on another page and pass parameter in url from table? Remove attribute "checked" of checkbox

Examples related to jquery-events

Failed to load resource: the server responded with a status of 500 (Internal Server Error) in Bind function Detect Close windows event by jQuery How to bind Events on Ajax loaded Content? Get clicked element using jQuery on event? jQuery click events firing multiple times jQuery.click() vs onClick Bootstrap onClick button event Difference between $(this) and event.target? Getting the class of the element that fired an event using JQuery Attaching click event to a JQuery object not yet added to the DOM