我有一个可拖动的项目,如果不是放在一个可丢弃的项目中,它将恢复。这很好用,直到用户在droppable中拖出一个项目。如果他们认为他们犯了一个错误,那么每当他们拉出可拖放对象时,它就会恢复为可放放对象。我更喜欢on out并停用draggable返回到它的原始容器。
我的代码如下,但我提供了a sample on jsFiddle。
HTML
<div id="origin">
<div id="draggable" class="ui-widget-content">
<p>I revert when I'm not dropped</p>
</div>
</div>
<div id="droppable" class="ui-widget-header">
<p>Drop me here</p>
</div>
JavaScript
$(function() {
$("#draggable").draggable({
revert: function(dropped) {
var dropped = dropped && dropped[0].id == "droppable";
if(!dropped) alert("I'm reverting!");
return !dropped;
}
}).each(function() {
var top = $(this).position().top;
var left = $(this).position().left;
$(this).data('orgTop', top);
$(this).data('orgLeft', left);
});
$("#droppable").droppable({
activeClass: 'ui-state-hover',
hoverClass: 'ui-state-active',
drop: function(event, ui) {
$(this).addClass('ui-state-highlight').find('p').html('Dropped!');
},
out: function(event, ui) {
// doesn't work but something like this
ui.draggable.mouseup(function () {
var top = ui.draggable.data('orgTop');
var left = ui.draggable.data('orgLeft');
ui.position = { top: top, left: left };
});
}
});
});
发布于 2011-04-26 01:44:09
我不确定这是否适用于您的实际使用,但它适用于您的测试用例-在http://jsfiddle.net/sTD8y/27/更新。
我只是这样做的,只有当项目没有被删除时,才会使用内置的还原。如果已将其删除,则手动执行还原。您可以通过检查实际的CSS属性将其调整为某个计算出的偏移量,但我将允许您使用它,因为它在很大程度上依赖于draggable的CSS及其周围的DOM结构。
$(function() {
$("#draggable").draggable({
revert: function(dropped) {
var $draggable = $(this),
hasBeenDroppedBefore = $draggable.data('hasBeenDropped'),
wasJustDropped = dropped && dropped[0].id == "droppable";
if(wasJustDropped) {
// don't revert, it's in the droppable
return false;
} else {
if (hasBeenDroppedBefore) {
// don't rely on the built in revert, do it yourself
$draggable.animate({ top: 0, left: 0 }, 'slow');
return false;
} else {
// just let the built in revert work, although really, you could animate to 0,0 here as well
return true;
}
}
}
});
$("#droppable").droppable({
activeClass: 'ui-state-hover',
hoverClass: 'ui-state-active',
drop: function(event, ui) {
$(this).addClass('ui-state-highlight').find('p').html('Dropped!');
$(ui.draggable).data('hasBeenDropped', true);
}
});
});
发布于 2011-04-26 03:15:09
如果您想要将元素还原到源位置(如果它没有被放到#droppable
元素中),只需在脚本的开头保存可拖动对象的原始父元素(而不是位置),如果您验证它没有被放入#droppable
中,那么只需将#draggable
的父元素恢复到这个原始元素即可。
因此,请替换以下内容:
}).each(function() {
var top = $(this).position().top;
var left = $(this).position().left;
$(this).data('orgTop', top);
$(this).data('orgLeft', left);
});
有了这个:
}).each(function() {
$(this).data('originalParent', $(this).parent())
});
在这里,您将拥有可拖动对象的原始父元素。现在,你必须在一个精确的时刻恢复它的父节点。
每次从droppable中拖出元素时,都会调用drop
,而不是在停止时。因此,您添加了大量的事件回调。这是错误的,因为您从未清理过mouseup
事件。revert
是一个很好的地方,您可以挂接回调并检查元素是放在#droppable
元素的内部还是外部,而您现在正在做这件事,所以,只需删除drop
回调即可。
当元素被拖放,并且需要知道它是否应该恢复时,您可以肯定地知道,在新的拖动开始之前,您将不会与用户进行任何其他交互。因此,使用您用来知道它是否应该恢复或知道的相同条件,让我们用一段代码替换这个alert
:将父元素恢复到原始originalPosition
,并从draggable
内部重置div。revert属性是在_mouseStart
时设置的,因此,如果您更改了元素的所有者,则应该重新设置它,以便使revert的动画转到适当的位置。因此,让我们将其设置为{top: 0, left: 0}
,使动画转到元素的原点:
revert: function(dropped) {
var dropped = dropped && dropped[0].id == "droppable";
if(!dropped) {
$(this).data("draggable").originalPosition = {top:0, left:0}
$(this).appendTo($(this).data('originalParent'))
}
return !dropped;
}
就是这样!你可以在这里检查它的工作情况:http://jsfiddle.net/eUs3e/1/
请考虑到,如果在任何jQuery的UI更新中,revert
或originalPosition
的行为发生变化,您将需要更新代码才能使其正常工作。请记住这一点。
如果你需要一个不使用对ui.draggable内部调用的解决方案,你可以让你的body
成为一个可丢弃的元素,并将greedy
选项定义为false
。您必须确保您的body
元素占据整个屏幕。
祝好运!
发布于 2013-05-09 04:07:28
如果有人感兴趣,这里是我对这个问题的解决方案。它完全独立于Draggable对象工作,而是使用Droppable对象上的事件。它工作得很好:
$(function() {
$(".draggable").draggable({
opacity: .4,
create: function(){$(this).data('position',$(this).position())},
cursor:'move',
start:function(){$(this).stop(true,true)}
});
$('.active').droppable({
over: function(event, ui) {
$(ui.helper).unbind("mouseup");
},
drop:function(event, ui){
snapToMiddle(ui.draggable,$(this));
},
out:function(event, ui){
$(ui.helper).mouseup(function() {
snapToStart(ui.draggable,$(this));
});
}
});
});
function snapToMiddle(dragger, target){
var topMove = target.position().top - dragger.data('position').top + (target.outerHeight(true) - dragger.outerHeight(true)) / 2;
var leftMove= target.position().left - dragger.data('position').left + (target.outerWidth(true) - dragger.outerWidth(true)) / 2;
dragger.animate({top:topMove,left:leftMove},{duration:600,easing:'easeOutBack'});
}
function snapToStart(dragger, target){
dragger.animate({top:0,left:0},{duration:600,easing:'easeOutBack'});
}
https://stackoverflow.com/questions/5735270
复制相似问题