Jquery draggable issue

2020-07-25 02:41发布

问题:

Basically what I want is that while dragging, if I go outside the containment area and release the mouse click there, the draggable element just sticks to the border from where I left the containement area. And when I move my cursor back in, the element sticks back to the cursor. It doesnt looks nice when you are just moving your cursor(not dragging) and the element is still getting dragged.

Here is a fiddle to play with. Just drag and release the cursor outside the output area, you will get what I am talking about.

I was thinking of two ways

  1. Restrict mouse movement to the containmenet area while being dragged(I searched for it and didnt find how to do it. Mayb thats not possible ?)

  2. Revert the draggable to its position if the cursor leaves the containement area. (Still couldnt find a way to do this)

Any way or more bright ideas to achieve this ???

Relevant Code (for stackoverflow)

回答1:

I think it's because it's in an iframe. It would be like dragging outside your browser. The mouseup event will not register in the page.

It looks like chrome doesn't allow that but firefox does.

Try this: fiddle

$('body').mouseleave(function()
    {
    $(document).trigger("mouseup");
    });

It's your solution without setting the event everytime.

The overkill version (this will allow the user to temporarily (1 second) leave the iframe and return without losing the drag):

$('body').prop('mouseuptimer',null)
    .mouseleave(function()
        {
        var objTimer = setTimeout(function() 
            {
            $(document).trigger("mouseup")
            }, 1000);
        $(document).prop('mouseuptimer', objTimer);
        })
    .mouseenter(function()
        {
        var objTimer = $(document).prop('mouseuptimer');
        if (objTimer) clearTimeout(objTimer);
        });
$(function() 
    {
    $( "#sortable" ).sortable({revert: true });
    $( "#draggable" ).draggable({
        connectToSortable: "#sortable",
        helper: "clone",
        revert: "invalid" });
    $( "ul, li" ).disableSelection();
    });

edit:

To answer your first question:

You can contain a draggable by adding 'containment' to the options i.e.:

$( "#draggable" ).draggable({
    connectToSortable: "#sortable",
    helper: "clone",
    revert: "invalid",
    containment: "document" });

But this can only contain the dragged element to the bounding box (in this case the "document", but it could also be i.e. "parent" or "#somediv"). The mouse cursor will still be able to move anywhere outside the iframe and dispatch events from there, beyond the scope of the iframe document.



回答2:

Ok, I found a workaround for this. Works In IE8 and Chrome.

Added this code for the draggable element.

drag: function(){
     $('body').mouseleave(function(){
          $('body').mouseup();
     });
}

Working Fiddle

EDIT: Thanks to Rembunator for pointing out the flaw, I decided to use .one() for better performance, and shift the code from drag to start

start: function(){
     $('body').one("mouseleave", function(){
          $('body').mouseup();
     });
}

EDIT 2:

Finally found a solution for it.

Here is the code:

var flag=true;
start: function( event, ui ){
    if(flag){
         flag = false;
         $('body').one("mouseleave", function(){
             $('body').mouseup();
              flag = true; //event occured, rebind
          });
     }
     else{
         flag = false;
     }
}

Thanks to Rembunator for his help