Reputation: 7057
I would like to execute some function when the user presses for 2 seconds
on a div.
Is it possible ?
Here is my code to detect the click on the div
$('div').mousedown(function() {
});
Upvotes: 39
Views: 49522
Reputation: 1130
We can calculate the time difference when the mouse clicks and leave. We can get the timestamp
when you click and release a button
or div
using mousedown
and mouseup
Here's an example to detect the simple click and 2 seconds
long press. Here I have done with a button
press. Similarly, you can use div
$(document).ready(function () {
var pressTime; // store the press time
$("#pressHere").on('mouseup', function () {
var holdTime = 2000; // 2 seconds for long press
if (new Date().getTime() >= (pressTime + holdTime))
$("#status").text("It's a Long Press...");
else
$("#status").text("It's a Short Press...");
}).on('mousedown', function () { // When Button Release
pressTime = new Date().getTime();
}).on('mouseleave', function () { // When Button Leave
pressTime = 0;
});
});
.input-bar-item {
display: table-cell;
}
.button-item {
margin: 20px;
width: 30%;
}
.width100 {
width: 60%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="input-bar-item button-item">
<button class="btn btn-info" id="pressHere">Press Me</button>
</div>
<div class="input-bar-item width100" id="status"></div>
Upvotes: 1
Reputation: 2284
My solution
Usage:
$("#button").longClick(
function() { //longclick callback
console.log("long clicked");
},
function() { //click callback (optional)
console.log("clicked");
},
1000 //Time in ms. Optional
});
JSFillde: https://jsfiddle.net/01em4yvc/
Code:
(function() {
/**
* Register a function to handle long click via mouse or touch
*
* @author Torge Kummerow
*/
$.fn.longClick = function (longClickCallback, clickCallback = null, timeout = 1000) {
if (longClickCallback == null && clickCallback == null)
throw new Error("Neither longClickCallback nor clickCallback defined");
let _t = this; //Nailing this to _t for all following function contexts
//Struct to keep track of the state.
let state = {
started : false,
triggered : false,
timer : null,
clear : function () {
state.started = false;
state.triggered = false;
if (state.timer != null)
clearTimeout(state.timer);
state.timer = null;
}
}
//Disable native longpress touch handling on touch devices (like copy/paste)
$(_t).css({
'-webkit-touch-callout' : 'none',
'-webkit-user-select' : 'none',
'-khtml-user-select' : 'none',
'-moz-user-select' : 'none',
'-ms-user-select' : 'none',
'user-select' : 'none'
});
//Handling events
$(_t).on('mousedown mouseup mouseout touchstart touchend touchcancel touchmove', function(event) {
switch (event.type) {
case 'touchstart' :
case 'mousedown' :
if (state.started)
return; //Click handling alread in progress. A touch will trigger both touchstart and mousedown (but mousedown only after touchend)
state.clear(); //To be safe
state.started = true;
//starting a timer when to handle the long press
state.timer = setTimeout(function() {
//User pressed for long enough to handle the press
if (longClickCallback != null && state.started && !state.triggered) {
state.triggered = true;
longClickCallback(event);
}
}, timeout);
break;
case 'touchend' :
case 'mouseup' :
if (clickCallback != null && state.started && !state.triggered) {
//No long press or click handled yet, So fire normal click event if callback was provided
state.triggered = true;
clickCallback(event);
}
/* Delay clearing state because the event order is
* touchstart ... touchend mousedown mouseup
* if not done this way, mousedown will trigger a second click
* This also means the user can only click once every 100 ms which should be fine normally
*/
setTimeout(function() {
state.clear();
}, 100);
break;
case 'mouseout' :
case 'touchcancle' :
// Cancel progress as mouse was moved outside of the element or finger outside of the canvas
state.clear();
break;
case 'touchmove' :
// There is no touchout event, so we check ourself if the user is still above the element after
// moving. Note that with scrollable content, this will always return false, even if the finger
// actually is outside, as the scroll area is ment to move with the finger.
// This is especially happening for "rubberband" effects at the edge of scrollable content
let x = event.originalEvent.touches[0].pageX;
let y = event.originalEvent.touches[0].pageY;
let elBelowMouse = document.elementFromPoint(x,y);
if ($(_t)[0] != elBelowMouse) {
state.clear();
}
break;
}
});
return this;
};
})();
Upvotes: 0
Reputation: 31
So this is obviously a long way in the future, but for people who want to do this still, a super simple and pretty elegant way to do this is by combining the clearTimeout function with mouseup / mouseout events:
$('#button').mousedown(function(){
var timer = setTimeout(
() => {alert('long press occurred');}, 600
);
}).mouseup(function(){
clearTimeout(timer);
}).mouseout(function(){
clearTimeout(timer);
});
#button {
width: 50px;
height: 50px;
background-color: blue;
color: white;
display: flex;
flex-direction: column;
text-align: center;
justify-content: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="button">press here</div>
Upvotes: 3
Reputation: 31
Short-click & Long-click events - short press prevented in long press
//from e-OS menu script
var longpress = 800;
var start;
var timer;
//short press - show e-OS system menu
//long press - show e-OS settings
$( "#e-OS-menu" ).on( 'mousedown', function( e ) {
start = new Date().getTime();
timer = setTimeout(function(){ console.log('long press!'); }, longpress)
}).on( 'mouseleave', function( e ) {
start = 0;
clearTimeout(timer);
}).on( 'mouseup', function( e ) {
if ( new Date().getTime() < ( start + longpress ) ) {
clearTimeout(timer);
console.log('short press!');
}
});
Upvotes: 3
Reputation: 145
I know this question is pretty old now, but I was looking for something like this and found that Buley's answer was close to what I needed. I figured I'd post what I've done with it to have it function without the mouse up, sort of like an Android longtouch.
// Set the duration of the long press and declare a couple variables
var longpress = 1000;
var start;
var divMouseDown;
// Check for mousedown on the element of choice
$("#element").on('mousedown', function(e){
// Get the time it was clicked
start = new Date().getTime();
// See if mouse is still being held down after the longpress duration
divMouseDown = setTimeout(function(){
// What we want to happen when mouse is clicked and held for 1 second
}, longpress);
// If the mouse leaves the element or is released before the long touch event,
// reset variables and stop the function from triggering
$("#element").on('mouseup mouseleave', function(){
if (divMouseDown) {
clearTimeout(divMouseDown);
}
start = 0;
e.stopPropagation();
} );
} );
Upvotes: 3
Reputation: 5181
In the two years since this question was asked an awesome plugin called jQuery Finger was invented:
http://ngryman.sh/jquery.finger/
$('div').on('press', function(e) {
console.log(this, e);
});
Upvotes: 4
Reputation: 31
Simple. No need for long uneccesary coding.
(function(){
// how many milliseconds is a long press?
var offset = 500;
$(".button").on('mousedown', function(e){
// holds the start time
$(this).data('start',new Date().getTime());
$(this).addClass("selected");
}).on('mouseup', function(e){
if (new Date().getTime() >= ($(this).data('start') + offset)){
//alert('ur click lasted for over 2 secs');
$(this).addClass("selected");
}else{
$(this).removeClass("selected");
}
}).on('mouseleave', function(e){
start = 0;
//you can add destroy lingering functions on mouse leave
});
}());
http://jsfiddle.net/donddoug/8D4nJ/
Upvotes: 1
Reputation: 119
This solution executes the action after the time you set. It also cancels the action if you leave the pressed element with the mouse.
var longpress={
pressed:false,
longpressed:false,
presstime:1000
};
$('#element').on( 'mousedown' , function( event ) {
longpress.longpressed=false;
longpress.pressed=true;
longpress.timeout=setTimeout(function() {
longpress.longpressed=true;
//Long press action here!
},longpress.presstime);
}).on( 'mouseup' , function( event ) {
clearTimeout(longpress.timeout);
if (!longpress.longpressed && longpress.pressed) {
longpress.pressed=false;
//Short press action here!
}
}).on('mouseleave', function( event ) {
clearTimeout(longpress.timeout);
longpress.pressed=false;
});
Upvotes: 2
Reputation: 21
Upgrading and merging Editor and Kevin B replies you can have a fully functional, multi divs, hold-catcher with:
// Global delta msec timeout
var delta = 1500;
$("#foo").on('mousedown', function(event) {
var thisElement = $(event.currentTarget);
var deltaTimer = setTimeout(function(){
console.log('long press!');
thisElement.removeData('startTimestamp');
}, delta);
thisElement.data('startTimestamp', new Date().getTime());
thisElement.data('timer', deltaTimer);
}).on('mouseleave', function(event) {
var thisElement = $(event.currentTarget);
clearTimeout(thisElement.data('timer'));
thisElement.removeData('startTimestamp');
thisElement.removeData('timer');
}).on('mouseup', function(event) {
var thisElement = $(event.currentTarget);
var startTimestamp = thisElement.data('startTimestamp');
clearTimeout(thisElement.data('timer'));
if (startTimestamp !== undefined && !isNaN(parseInt(startTimestamp))) {
if (new Date().getTime() >= (startTimestamp + delta))
console.log('long press!');
else
console.log('short press!');
}
thisElement.removeData('startTimestamp');
thisElement.removeData('timer');
});
Upvotes: 2
Reputation: 6762
You can use the following code (tested in JSFiddle):
$('#foo').mousedown(function(){
$(this).data('lastPressed', new Date().getTime());
}).mouseup(function(){
var lastPressed = $(this).data('lastPressed');
if (lastPressed){
var duration = new Date().getTime() - lastPressed;
$(this).data('lastPressed', false);
if (duration > 2000) {
alert('Your click lasted more than 2 seconds.');
} else {
alert('Your click lasted less than 2 seconds.');
}
}
}).mouseout(function(){
$(this).data('lastPressed', false);
});
Upvotes: 2
Reputation: 29208
Just watch both mousedown
and mouseup
and calculate the difference. Here's an example.
(function() {
// how many milliseconds is a long press?
var longpress = 3000;
// holds the start time
var start;
jQuery( "#pressme" ).on( 'mousedown', function( e ) {
start = new Date().getTime();
} );
jQuery( "#pressme" ).on( 'mouseleave', function( e ) {
start = 0;
} );
jQuery( "#pressme" ).on( 'mouseup', function( e ) {
if ( new Date().getTime() >= ( start + longpress ) ) {
alert('long press!');
} else {
alert('short press!');
}
} );
}());
Upvotes: 31
Reputation: 95031
Add a throttle that only allows the click to happen after 2 seconds of mousedown.
var timer;
$('div').on("mousedown",function(){
timer = setTimeout(function(){
alert("WORKY");
},2*1000);
}).on("mouseup mouseleave",function(){
clearTimeout(timer);
});
Edit: I added mouseleave too since if the mouse leaves the element and then triggers mouseup, it won't stop the timer.
Upvotes: 38
Reputation: 2335
You can get the timestamp when you detect the click on the div thanks to mousedown
. Similarly you can get the timestamp when you detect the click release thanks to mouseup
.
You then need to compare these two timestamps, if they are greater than 2 seconds (or 2000milliseconds) then you execute your function.
Upvotes: 1