MJS
MJS

Reputation: 87

jQuery - don't fire 'click' on 'mousemove'

I created a Fiddle to demonstrate my situation.

I want to not fire the click event when the user is panning--only if it's just a simple click. I've experimented with different placements of .off() and .on() to no avail.

Thanks in advance for your help.

Upvotes: 3

Views: 3331

Answers (6)

Jasper
Jasper

Reputation: 76003

You can use the mousemove/mousedown events to set a flag that can be used in the click event handler to determine if the user was clicking or panning. Something like:

//set a flag for the click event to check
var isClick = false;

//bind to `mousedown` event to set the `isClick` flag to true
$(document).on('mousedown', function (event) {
    isClick = true;

//bind to `mousemove` event to set the `isClick` flag to false (since it's not a drag
}).on('mousemove', function () {
    isClick = false;

//bind to `click` event, check to see if the `isClick` flag is set to true, if so then this is a click, otherwise this is a drag
}).on('click', function () {
    if (isClick) {
        console.log('click');
    } else {
        console.log('drag');
    }
});​​

Here is a demo: http://jsfiddle.net/SU7Ef/

Upvotes: 0

satoshi
satoshi

Reputation: 4103

This solution solves your problem:

var bClicking = false,
    moved = false;;
var previousX, previousY;
var $slider = $('#slider'),
    $wrapper = $slider.find('li.wrapper'),
    $img = $slider.find('img.foo');

$img.on('click', function()
{
    if(!moved)
    {
        doZoom();
    }
});

$wrapper.mousedown(function(e) {
    e.preventDefault();

    previousX = e.clientX;
    previousY = e.clientY;
    bClicking = true;
    moved = false;
});

$(document).mouseup(function(e) {
    bClicking = false;
});

$wrapper.mousemove(function(e) {
    if (bClicking)
    {
        moved = true;
        var directionX = (previousX - e.clientX) > 0 ? 1 : -1;
        var directionY = (previousY - e.clientY) > 0 ? 1 : -1;

        $(this).scrollLeft($(this).scrollLeft() + 10 * directionX);
        $(this).scrollTop($(this).scrollTop() + 10 * directionY);

        previousX = e.clientX;
        previousY = e.clientY;
    }
});

function doZoom() {
    $img.animate({
        height: '+=300',
        width: '+=300'
    }, 500, function() {
        //animation complete
    });
}​

Basically, it calls doZoom() only when the mouse has not moved between the mousedown and the mouseup events.

Upvotes: 0

Waxen
Waxen

Reputation: 1782

http://jsfiddle.net/Waxen/syTKq/3/

Updated your fiddle to do what you want. I put the re-binding of the event in a timeout so it wouldn't trigger immediately, and adjusted the mousemove to

Upvotes: 2

Vigrond
Vigrond

Reputation: 8198

I added a "panning" bool for a solution to your problem:

see http://jsfiddle.net/syTKq/4/

Basically, if the user has mousedown and mousemove, then panning is true. once mouseup panning is false. if just mousedown, panning is false, therefore zoom.

Upvotes: 0

Rok Kralj
Rok Kralj

Reputation: 48735

In on click event, you can detect whether mouse was pressed DOWN or UP. So let's analyse:

DRAG:
mouse down
mosue position changes
mouse up

CLICK:
mouse down
mouse up

You see - the difference is changed mouse position. You can record click coordinate in mouse down and then compare it when muse goes back up. If it is within some treshold, the action was a click.

Upvotes: 1

jbabey
jbabey

Reputation: 46647

The only way to tell between a "click" and a "pan" would be the time the mouse has spent held down. You could create a Date in the mousedown, then another in the mouseup, and only fire your click (zoom) event if the difference between the two dates is greater than some threshold (i would guess 1/10 of a second, but you may want to experiment)

Upvotes: 0

Related Questions