jQuery UI - Droppable 只接受一个可拖动
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3948447/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
jQuery UI - Droppable only accept one draggable
提问by Emil Avramov
I'm making an app, that is using one droppable div
and a few draggable div
s. How can I make the droppable to not accept more than one draggable div
? I Googled, but didn't find any workaround.
我正在制作一个应用程序,它使用一个 droppablediv
和几个可拖动的div
s。我怎样才能让 droppable 不接受多个可拖动div
?我用谷歌搜索,但没有找到任何解决方法。
A workaround came up in mi mind. How can i check is there's dropped element in this droppable div? If it's busy then revert this draggable, which is trying to be dropped
我想到了一个解决方法。我如何检查这个可放置的 div 中是否有放置的元素?如果它很忙,则恢复这个正在尝试删除的可拖动对象
回答by Likwid_T
OK found a nice solution for this, essentially on 'drop' I set the droppable to only accept the item which has been dragged into it.
好的,为此找到了一个很好的解决方案,基本上在“放置”时,我将放置项设置为仅接受已拖入其中的项目。
When you 'disable', the 'out' event that you need to re-initialize isn't available anymore, so instead I just switched the eligible items around.
当您“禁用”时,您需要重新初始化的“out”事件不再可用,因此我只是切换了符合条件的项目。
Then it's possible for me to use the OUT event to re-accept all draggable items and because nothing else is accepted the OUT won't be triggered by other draggables:
然后我可以使用 OUT 事件重新接受所有可拖动的项目,并且因为没有其他任何东西被接受,OUT 不会被其他可拖动的触发:
$(".drop-zone").droppable({
drop: function(event, ui) {
$(this).droppable('option', 'accept', ui.draggable);
},
out: function(event, ui){
$(this).droppable('option', 'accept', '.drag-item');
}
});
});
回答by Nick Craver
You can destroy the .droppable()
widget after the first drop
, like this:
您可以.droppable()
在 first 之后销毁小部件drop
,如下所示:
$(".droppable").droppable({
drop: function( event, ui ) {
$(this).droppable("destroy");
}
});
回答by Catfish
Easy Peasey. Just enable all the .drop-zone's when hovered over them, and then check if the currently hovered .drop-zone contains a draggable element
简单的皮西。只需在悬停在它们上方时启用所有 .drop-zone,然后检查当前悬停的 .drop-zone 是否包含可拖动元素
$('.drop-zone').droppable({
over: function(event, ui) {
// Enable all the .droppable elements
$('.droppable').droppable('enable');
// If the droppable element we're hovered over already contains a .draggable element,
// don't allow another one to be dropped on it
if($(this).has('.draggable').length) {
$(this).droppable('disable');
}
}
});
回答by Harrison Powers
This solution solves a major bug in Likwid_T's answer.
此解决方案解决了 Likwid_T 答案中的一个主要错误。
$('.draggable').draggable({
start: function(ev, ui) {
$('.ui-droppable').each(function(i, el) {
if (!$(el).find('.ui-draggable').length) $(el).droppable('enable');
});
}
});
$('.droppable').droppable({
drop: function(ev, ui) {
$(ev['target']).droppable('disable');
}
});
回答by Than Ngo Hoai
I spend many hours to figure it out and finally it works for me like this:
我花了很多时间来弄清楚,最后它像这样对我有用:
$( ".drop-zone" ).droppable({
classes: {
"ui-droppable-active": "ui-state-active",
"ui-droppable-hover": "ui-state-hover"
},
accept: function( draggable ){
if (!$(this).hasClass('dropped') || draggable.hasClass('dropped')){
return true;
}
return false;
},
drop: function( event, ui ) {
$(this).addClass('dropped');
ui.draggable.addClass('dropped');
},
out: function( event, ui ){
$(this).removeClass('dropped');
ui.draggable.removeClass('dropped');
}
});
回答by Stefano Luoni
How about this:
这个怎么样:
$(".drop-zone").droppable({
accept: function(draggable) {
return $(this).find("*").length == 0;
});
});
This way the accept funcion return true only when no elements have been dropped yet.
这样,只有当还没有删除任何元素时,accept 函数才返回 true。
回答by kasimir
You could also do it the other way around, by reverting the draggable when the droppable has a certain class or attribute (building on this example: https://stackoverflow.com/a/3418306/1005334).
您也可以反过来做,当 droppable 具有某个类或属性时恢复可拖动对象(基于此示例构建:https: //stackoverflow.com/a/3418306/1005334)。
So for example, using the rel
attribute (you could also use class
or something else), for the droppable:
例如,对于 droppable ,使用rel
属性(您也可以使用class
或其他东西):
$('.drop-zone').droppable({
drop: function () {
drop.attr('rel', 'filled');
}
});
And the draggable:
和可拖动的:
$('.draggable').draggable({
revert: function (droppable) {
if (droppable.attr('rel') == 'filled') {
return true;
}
}
});
回答by Sergey
To enable it, use the option: $(".selector").droppable({ disabled: **false** });
要启用它,请使用以下选项: $(".selector").droppable({ disabled: **false** });
回答by hagabaka
My solution is similar to Likwid_T's, except it uses the droppable drop
event as well as maintaining the links between draggables and droppables instead of droppable's out
event. I think the problem with using out
is that it is fired even when a draggable is dragged over an already "full" droppable and then "out" of it.
我的解决方案类似于 Likwid_T 的,除了它使用 droppabledrop
事件以及维护 draggables 和 droppables 之间的链接而不是 droppable 的out
事件。我认为使用的问题out
在于,即使将可拖动对象拖到已经“完整”的可放置对象上,然后将其“移出”,它也会被触发。
droppable({
drop: function(event, ui) {
var $droppable = $(this);
var $draggable = ui.draggable;
// If the draggable is moved from another droppable, unlink it from the old droppable
var oldDropped = $draggable.data('dropped');
if(oldDropped) {
$draggable.data('dropped', null);
oldDropped.data('dragged', null);
}
// Link the draggable and droppable
$draggable.data('dropped', $droppable);
$droppable.data('dragged', $draggable);
},
accept: function() {
// Only accept if there is no draggable already associated
return !$(this).data('dragged');
}
});
A related feature is that one dragging one item over a droppable that already has a draggable, the old one would get replaced and revert to its initial position. This is how I do it:
一个相关的功能是将一个项目拖到一个已经有一个可拖动的可放置对象上,旧的将被替换并恢复到其初始位置。这就是我的做法:
droppable({
drop: function(event, ui) {
var $droppable = $(this);
var $draggable = ui.draggable;
// Reset position of any old draggable here
var oldDragged = $droppable.data('dragged');
if(oldDragged) {
// In the CSS I have transitions on top and left for .ui-draggable, so that it moves smoothly
oldDragged.css({top: 0, left: 0});
oldDragged.data('dropped', null);
}
// If the draggable is moved from another droppable, unlink it from the old droppable
var oldDropped = $draggable.data('dropped');
if(oldDropped) {
$draggable.data('dropped', null);
oldDropped.data('dragged', null);
}
// Link the draggable and droppable
$draggable.data('dropped', $droppable);
$droppable.data('dragged', $draggable);
},
});