QUESTION:

Using jQuery, how can I imitate a click-and-hold event?


I am currently beating my head against a wall and cannot seem to figure out how to go about this!

I have also tried searching on google and in forums, but to no avail.

In my current example, I am using jQuery UI's .draggable().

Ideally, I would like to do the following:

  • Perform a click/mousedown on the div.
  • Imitate a click-and-hold event and be able to move the element freely.
  • On next click/mousedown, end click-and-hold event.

When I try functions like:

$("#drag").draggable().mousedown(function(e){
    e.preventDefault();
    return $(this).mousedown();
});

It then causes an infinite loop, which will eventually result in the browser crashing. However, I am not sure how one would go about initiating a constant .mousedown() event.

Here is a demo of what I currently have: http://jsfiddle.net/vPruR/16/ .

Any help would be greatly appreciated!


Solution 1:

I don't think there is some option to simulate the click-and-hold. Also it may create too much browser dependency.

So you could try something as below.

var click = false,
top = null,
left = null;

$(document).bind('mousemove', function (e) {
   if (click == true) {
      $('#drag').css({
         left: e.pageX - left,
         top: e.pageY - top
       });
    }
});

$('#drag').draggable().click(function(e) {
    top = e.pageY - $('#drag').position().top; 
    left = e.pageX - $('#drag').position().left;
    click = !click;
    return false;
});

$('html').click(function() {
    click = false;
});

DEMO: http://jsfiddle.net/dirtyd77/qbcQn/

Solution 2:

Wolf and Dom's solutions work great and are the basis for my solution, but you mentioned you were using jquery ui's draggable, so here is a possible solution using jquery ui's draggable object in conjunction with a droppable. I was trying to get the droppable's events to fire when a draggable dragged over them and dropped on them, so I utilized the built-in/private functions of the ui.mouse object that draggable inherits from and overrides.

$(document).ready(function(){
      var click = false

    $(document).bind('mousemove', function (e) {
        if (click == true) {
           $('#drag').data('uiDraggable')._mouseDrag(e);
        }
    });

    $('#drag').draggable().click(function(e) {
        if(!click){
            $(this).data('uiDraggable')._mouseCapture(e, true)
            $(this).data('uiDraggable')._mouseStart(e, true, true);
        }else{
            $(this).data('uiDraggable')._mouseUp(e);
            $(this).data('uiDraggable')._mouseStop(e);
        }
        click = !click;
        return false;
    });

    $('html').click(function() {
        click = false;
    });
});

Heres a fiddle. To see the droppable stuff, just uncomment the droppable stuff in the js.

Note: this solution is for the current jquery ui version (1.9.2), but may change in future versions because it does use private calls.