jQuery draggable + droppable:如何将删除的元素快照到删除的元素

时间:2021-09-14 20:37:30

I have my screen divided into two DIVs. In the left DIV I have a few 50x50 pixel DIVs, in the right DIV I have an empty grid made of 80x80 LIs. The DIVs on the left are draggable, and once dropped on a LI, they should snap to center of that LI.

我把屏幕分成两部分。在左边的DIV中,我有一些50x50像素的DIV,在右边的DIV中,我有一个由80x80 LIs做成的空网格。左边的女主角是可以拖拽的,一旦落在了一里,就应该迅速地落在那一里的中间。

Sounds simple, right? I just don't know how to get this done. I tried by manipulating the dropped DIV's top and left CSS properties to match those of the LI they're dropped into, but the left and top properties are relative to the left DIV.

听起来很简单,对吧?我只是不知道该怎么做。我试着操作掉的DIV的顶部和左侧CSS属性来匹配它们被放入的LI属性,但是左侧和顶部属性是相对于左侧DIV的。

How can I best have the dropped element snap to the center of the element it's dropped into? That's gotta be simple, right?

如何最好地将被删除的元素吸附到元素的中心呢?这很简单,对吧?

Edit: I'm using jQuery UI 1.7.2 with jQuery 1.3.2.

编辑:我在jQuery 1.3.2中使用jQuery UI 1.7.2。

Edit 2: For whoever else has this problem, this is how I fixed it:

编辑2:对于其他有这个问题的人,我是这样解决的:

I used Keith's solution of removing the dragged element and placing it inside the dropped-on element in the drop callback of the droppable plugin:

我使用了Keith的解决方案,删除了拖拽元素,并将它放在droppable插件的drop callback中的拖放元素中:

function gallerySnap(droppedOn, droppedElement)
{
    $(droppedOn).html('<div class="drop_styles">'+$(droppedElement).html()+'</div>' );
    $(droppedElement).remove();
}

I don't the dropped element to be draggable again, but if you do, just bind draggable to it again.

我并没有将被删除的元素再次拖拽,但是如果您这样做了,只需再次绑定拖拽元素。

For me this method also solved the problem I had when positioning the dropped elements (which would be relative to the left DIV) and scrolling inside the second DIV. (Elements would remain fixed on page, now they scroll along).

对我来说,这个方法还解决了我在放置掉的元素(相对于左DIV)和在第二个DIV中滚动时遇到的问题(元素将保持在页面上,现在它们继续滚动)。

I did play with the snap options to make it look good while dragging, so thanks to karim79 for that suggestion.

我在拖拽的时候用了抓拍选项使它看起来很好,所以感谢karim79的建议。

I probably won't win any Awesome Code prizes with this, so if you see room for improvement, please share!

我可能不会用这个赢得任何可怕的代码奖,所以如果你看到改进的空间,请分享!

7 个解决方案

#1


16  

I had a similar problem - I worked around it by manually removing the dragged element from its old parent and adding it to the dropped on element.

我遇到了类似的问题——我通过从旧的父元素中手动删除拖拽元素并将其添加到drop on元素来解决这个问题。

#2


70  

I found that Keith's method worked for me. Since his answer doesn't include an example implementation, I'll post mine:

我发现基思的方法对我有效。由于他的回答不包含示例实现,我将发布我的答案:

$('.dropTarget').droppable({
    drop: function(ev, ui) {
        var dropped = ui.draggable;
        var droppedOn = $(this);
        $(dropped).detach().css({top: 0,left: 0}).appendTo(droppedOn);
    }
});

or, slightly more concisely:

或者,更简洁:

$('.dropTarget').droppable({
    drop: function(ev, ui) {
        $(ui.draggable).detach().css({top: 0,left: 0}).appendTo(this);
    }
});

#3


10  

Thanks for your post - it helped me in the right direction. I find it a bit cleaner to set the position properties of the draggable object instead of messing with the HTML code. This sets the position to the top left corner of the droppable object, but you can modify to have it centered as well.

谢谢你的帖子——它帮我找到了正确的方向。我发现,设置可拖动对象的位置属性,而不是干扰HTML代码,这一点更简洁。这将把位置设置为droppable对象的左上角,但是您也可以修改为将其居中。

drop: function(event, ui) {
   $(ui.draggable).css('top', $(this).position().top);
   $(ui.draggable).css('left', $(this).position().left);
}

#4


3  

I found that when you do the drag, jQuery UI adds an inline to tell you where you dropped it. Below is a sample of the code that I used to snap it into place

我发现当您执行拖拽时,jQuery UI会添加一个内联来告诉您在哪里删除它。下面是我用来将其压缩到合适位置的代码示例

$('.droppable').droppable({ drop: function(ev, ui) { 
    //Get Details of dragged and dropped
    var draggedclass = ui.draggable.attr('class'),
        droppedclass = 'class' + $(this).attr('name').toLowerCase();

    //update the classes so that it looks od.       
    ui.draggable.removeClass(draggedclass).addClass(droppedclass);  
    ui.draggable.removeAttr('style');
});

#5


3  

$("form li").draggable({snap:'.ui-droppable', snapMode:'inner', revert:true});
$('.drop').droppable({drop:function(ev, ui)
                           {$(ui.draggable).appendTo($(this))
                                           .css({position:'static', left:'0px', top:'0px'})
                                           .draggable('option', 'disabled', false)
                                           .css({position:'relative'});
                           }
                     }
                    );

#6


0  

If the divs on the left are actually in the lis on the right (which you can confirm with Firebug), and if the lis are all in a ul (as they should be), try one or both of the following:

如果左边的divs实际上在右侧的lis中(您可以使用Firebug进行确认),如果lis都在ul中(应该是这样),请尝试以下两种方法:

ul#right_div {
  text-align: center;
}

ul#right_div li {
  text-align: center;
}

#7


0  

based on Barry's code, what if we d like to add an option with an "x" button the element to be detached again from the new parent and be reattached to the initial?

根据Barry的代码,如果我们想添加一个带有“x”按钮的选项,元素将再次与新父元素分离并重新连接到初始元素,会怎么样?

i thought sth like this, but didn't seem to work.. to make some sort of a variable that hold initial state

我想过这样的事,但似乎行不通。使某种具有初始状态的变量

var flag;
$('.draggable-div').draggable({
    revert: 'invalid',
    stop: function(){
        $(this).draggable('option','revert','invalid');
        $(this).find('.undo').show();
    flag=$(this).parent();
    }
});


$('.draggable-div').find('.undo').click(function(i, e) {
    var $div = $(this).parent();
$($div).detach().appendTo(flag);
 }

sth is definately wrong but i don't know if you can get the concept... just being able to reverse whatever you have dropped to their initial state.

某事物肯定是错误的,但我不知道你是否能理解……只要能够把你所放弃的东西倒转到它们的初始状态。

#1


16  

I had a similar problem - I worked around it by manually removing the dragged element from its old parent and adding it to the dropped on element.

我遇到了类似的问题——我通过从旧的父元素中手动删除拖拽元素并将其添加到drop on元素来解决这个问题。

#2


70  

I found that Keith's method worked for me. Since his answer doesn't include an example implementation, I'll post mine:

我发现基思的方法对我有效。由于他的回答不包含示例实现,我将发布我的答案:

$('.dropTarget').droppable({
    drop: function(ev, ui) {
        var dropped = ui.draggable;
        var droppedOn = $(this);
        $(dropped).detach().css({top: 0,left: 0}).appendTo(droppedOn);
    }
});

or, slightly more concisely:

或者,更简洁:

$('.dropTarget').droppable({
    drop: function(ev, ui) {
        $(ui.draggable).detach().css({top: 0,left: 0}).appendTo(this);
    }
});

#3


10  

Thanks for your post - it helped me in the right direction. I find it a bit cleaner to set the position properties of the draggable object instead of messing with the HTML code. This sets the position to the top left corner of the droppable object, but you can modify to have it centered as well.

谢谢你的帖子——它帮我找到了正确的方向。我发现,设置可拖动对象的位置属性,而不是干扰HTML代码,这一点更简洁。这将把位置设置为droppable对象的左上角,但是您也可以修改为将其居中。

drop: function(event, ui) {
   $(ui.draggable).css('top', $(this).position().top);
   $(ui.draggable).css('left', $(this).position().left);
}

#4


3  

I found that when you do the drag, jQuery UI adds an inline to tell you where you dropped it. Below is a sample of the code that I used to snap it into place

我发现当您执行拖拽时,jQuery UI会添加一个内联来告诉您在哪里删除它。下面是我用来将其压缩到合适位置的代码示例

$('.droppable').droppable({ drop: function(ev, ui) { 
    //Get Details of dragged and dropped
    var draggedclass = ui.draggable.attr('class'),
        droppedclass = 'class' + $(this).attr('name').toLowerCase();

    //update the classes so that it looks od.       
    ui.draggable.removeClass(draggedclass).addClass(droppedclass);  
    ui.draggable.removeAttr('style');
});

#5


3  

$("form li").draggable({snap:'.ui-droppable', snapMode:'inner', revert:true});
$('.drop').droppable({drop:function(ev, ui)
                           {$(ui.draggable).appendTo($(this))
                                           .css({position:'static', left:'0px', top:'0px'})
                                           .draggable('option', 'disabled', false)
                                           .css({position:'relative'});
                           }
                     }
                    );

#6


0  

If the divs on the left are actually in the lis on the right (which you can confirm with Firebug), and if the lis are all in a ul (as they should be), try one or both of the following:

如果左边的divs实际上在右侧的lis中(您可以使用Firebug进行确认),如果lis都在ul中(应该是这样),请尝试以下两种方法:

ul#right_div {
  text-align: center;
}

ul#right_div li {
  text-align: center;
}

#7


0  

based on Barry's code, what if we d like to add an option with an "x" button the element to be detached again from the new parent and be reattached to the initial?

根据Barry的代码,如果我们想添加一个带有“x”按钮的选项,元素将再次与新父元素分离并重新连接到初始元素,会怎么样?

i thought sth like this, but didn't seem to work.. to make some sort of a variable that hold initial state

我想过这样的事,但似乎行不通。使某种具有初始状态的变量

var flag;
$('.draggable-div').draggable({
    revert: 'invalid',
    stop: function(){
        $(this).draggable('option','revert','invalid');
        $(this).find('.undo').show();
    flag=$(this).parent();
    }
});


$('.draggable-div').find('.undo').click(function(i, e) {
    var $div = $(this).parent();
$($div).detach().appendTo(flag);
 }

sth is definately wrong but i don't know if you can get the concept... just being able to reverse whatever you have dropped to their initial state.

某事物肯定是错误的,但我不知道你是否能理解……只要能够把你所放弃的东西倒转到它们的初始状态。