如果内部 droppable 不接受draggable,则防止 drop 事件传播到父级
我有一个可放置的 div#space
和一个可拖动的 li.element
集合。当我在 div#space
中拖动 li.element
时,会创建一个新的 ul.group
,即 li.element
code> 被附加到 ul.group
中,最后 ul.group
被设置为可删除。
鉴于
我希望这些元素的行为如下:
- 当将
li.element
放入不包含它的ul.group
时, 当将li.element
放入ul.group
时,li.element
将被添加到 - ul.group 中确实包含它的代码>,
li.element
将恢复到其原始位置 - 当将
li.element
放入div#space
中(ul 之外)时, .group
) 如上所述,创建了一个新组。
问题是,当一个元素被放置在不接受它的 ul.group
上时,父级 div#space
将捕获该事件并创建一个新组。
ul.grpup
有一个 accept 函数,用于检查可放置元素是否为元素以及是否尚未被删除。
newULGroup.droppable({
drop: ...
accept: function(ui)
{
var isElement = ui.hasClass('element')
var elementId = '.' + ui.data().id
var isAlreadyPresent = $(this).find(elementId).length > 0
return isElement && (!isAlreadyPresent)
},
greedy: true
});
如果不接受所有内容并忽略放置处理程序中的内容,您将如何实现此行为? (我没有尝试过,但我想这会起作用)
编辑
尝试修复它
我修补了 jquery-ui-1.8.4.js 以将事件传递给接受函数。现在我可以使用 $(event).stopPropagation()
停止传播,但我必须手动将可拖动助手动画恢复到其原始位置以模拟恢复,然后将其从 dom 中删除。
accept: function(ui, event)
{
var isCriteria = ui.hasClass('criteria')
var criteriaId = '.' + ui.data().id
var isAlreadyPresent = $(this).find(criteriaId).length > 0
var accepted = isCriteria && (!isAlreadyPresent)
if (event && !accepted)
{
$(event.target).animate(ui.offset(), {complete: function() {$(this).remove()}})
$(event).stopPropagation()
}
return accepted
}
不幸的是,它似乎也破坏了原始元素的可拖动行为。为什么,哦为什么?
I have a droppable div#space
and a collection of draggable li.element
. When I drag an li.element
in the div#space
a new ul.group
is created, the li.element
is appended to the ul.group
and finally the ul.group
is made droppable.
Given
I would like these elements to behave as follows:
- when an
li.element
is dropped in theul.group
that does not contain it, theli.element
will be added to theul.group
- when an
li.element
is dropped in theul.group
that does contain it, theli.element
will be reverted to it's original position - when an
li.element
is dropped in thediv#space
(outside aul.group
) an new group is created as mentioned above.
The problem is that when an element is dropped on an ul.group
that does not accept it the parent div#space
will catch the event and will create a new group.
The ul.grpup
has an accept function that checks if the droppable is an element and if it's not already been dropped.
newULGroup.droppable({
drop: ...
accept: function(ui)
{
var isElement = ui.hasClass('element')
var elementId = '.' + ui.data().id
var isAlreadyPresent = $(this).find(elementId).length > 0
return isElement && (!isAlreadyPresent)
},
greedy: true
});
How would you implement this behaviour if not by accepting everything and ignoring things in the drop handler? (I haven't tried but I guess that would work)
Edit
An attempt to fix it
I patched the jquery-ui-1.8.4.js to pass the event to the accept function. Now I can stop the propagation with $(event).stopPropagation()
, but I have to animate manually the draggable helper back to its original position to simulate the revert, then remove it from the dom.
accept: function(ui, event)
{
var isCriteria = ui.hasClass('criteria')
var criteriaId = '.' + ui.data().id
var isAlreadyPresent = $(this).find(criteriaId).length > 0
var accepted = isCriteria && (!isAlreadyPresent)
if (event && !accepted)
{
$(event.target).animate(ui.offset(), {complete: function() {$(this).remove()}})
$(event).stopPropagation()
}
return accepted
}
Unfortunately it seems to destroy the draggable behaviour from the original element as well. Why, oh why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
尽管使用了未记录的 jQuery.ui 功能,但我还是设法实现了类似的行为。
如果您查看
jquery.ui.draggable
实现(至少对于 v1.8.16),revert
选项也可以是一个函数。它的this
是可拖动元素,单个参数是接受放置的可放置元素,返回值是一个boolean
来指示是否恢复可拖动元素。因此,在您的情况下,您需要
div#space
和ul.group
始终接受 drop 并贪婪地drop 处理程序并仅在项目不在组中时处理该项目,但
revert
函数中执行类似的检查,并在其已在组中时恢复自身。I managed to achieve similar behavior, although using undocumented jQuery.ui feature.
If you look into the
jquery.ui.draggable
implementation (at least for v1.8.16) therevert
option can also be a function. It hasthis
being the draggable element, single parameter which is the droppable who accepted the drop, and return value is aboolean
to indicate whether to revert the draggable or not.So in your case you need to
div#space
andul.group
always accept drops and be greedydrop
handler and processes item only if it's not in the group yetrevert
function and revert itself if it's already in the group.