29

I've read several answers on stackoverflow pertaining to this situation, but none of the solutions are working.

I'm trying to do different things based upon whether a user clicks an element, or holds the mouse down on that element using jQuery.

Is it possible to accomplish this?

Edric
  • 24,639
  • 13
  • 81
  • 91
aperture
  • 2,905
  • 3
  • 35
  • 58
  • 1
    @MrOBrian setting global variables in mousedown and mouseup to true/false, then checking in click method for variable, but mouseup always fires first – aperture Sep 24 '12 at 20:47
  • you could try using a timer on mouse down that will then set a variable or bind the correct event so you know if the button was held down for at least a certain amount of time. – MrOBrian Sep 24 '12 at 20:51

4 Answers4

33

onMouseDown will trigger when either the left or right (or middle) is pressed. Similarly, onMouseUp will trigger when any button is released. onMouseDown will trigger even when the mouse is clicked on the object then moved off of it, while onMouseUp will trigger if you click and hold the button elsewhere, then release it above the object.

onClick will only trigger when the left mouse button is pressed and released on the same object. In case you care about order, if the same object has all 3 events set, it's onMouseDown, onMouseUp, then onClick. Each even should only trigger once though.

Details:

Anton Baksheiev
  • 2,211
  • 2
  • 14
  • 15
  • Yes, but I want onClick to not fire if the time between mousedown and mouseup is long enough. I'm comparing event timestamps now, and that kind of works. – aperture Sep 24 '12 at 21:34
22

Here's one approach

  1. set a variable to true
  2. make a function that will set it to false when called
  3. have a timer ( setTimeout() ) start counting down on mousedown()
  4. on mouseup, clear the timeout, and check if it the variable is true or false
  5. if it is false, call the function you want to happen on click
  6. In any case, set the variable back to true

This will do what you want. Here's a jsfiddle showing how it might work: http://jsfiddle.net/zRr4s/3/

daveyfaherty
  • 4,585
  • 2
  • 27
  • 42
12

Here's a solution that supports both clicks and holds:

// Timeout, started on mousedown, triggers the beginning of a hold
var holdStarter = null;
// Milliseconds to wait before recognizing a hold
var holdDelay = 500;
// Indicates the user is currently holding the mouse down
var holdActive = false;
// MouseDown
function onMouseDown(){
    // Do not take any immediate action - just set the holdStarter
    //  to wait for the predetermined delay, and then begin a hold
    holdStarter = setTimeout(function() {
        holdStarter = null;
        holdActive = true;
        // begin hold-only operation here, if desired
    }, holdDelay);
}
// MouseUp
function onMouseUp(){
    // If the mouse is released immediately (i.e., a click), before the
    //  holdStarter runs, then cancel the holdStarter and do the click
    if (holdStarter) {
        clearTimeout(holdStarter);
        // run click-only operation here
    }
    // Otherwise, if the mouse was being held, end the hold
    else if (holdActive) {
        holdActive = false;
        // end hold-only operation here, if desired
    }
}
// Optional add-on: if mouse moves out, then release hold
function onMouseOut(){
    onMouseUp();
}

Here's a demo: http://jsfiddle.net/M7hT8/1/

Originally based on daveyfaherty's solution. I know this question is from a while ago, but I'm sharing my solution for anyone who finds this via a search.

bassguy007
  • 145
  • 1
  • 7
  • And indeed, a helpful one. Thanks! – GuyC Sep 14 '17 at 02:24
  • I'm using this solution for a Cordova app, but with the newer Pointer Events API for unified support for touch and mouse input. See https://mobiforge.com/design-development/html5-pointer-events-api-combining-touch-mouse-and-pen – Rohan 'HEXcube' Villoth Feb 02 '18 at 10:36
-1
//last mouse coordinate
var mouseX = 0;
//epsilon interval
var mouseEps = 10;

function mouseDownHandler(e) {
    e.preventDefault();
    mouseX = e.clientX;
};

function mouseUpHandler(e) {
    e.preventDefault();
    if (Math.abs((mouseX - e.clientX)) < mouseEps) {
        clickHandler(e);
    }
};

function clickHandler(e) {
};
StuS
  • 817
  • 9
  • 14