概述:
我有一个使用jquery.event.drag和jquery.event.drop的网页。 我需要能够拖放到不断添加到dom中的元素,即使在拖动开始之后也是如此。
问题:
当dragstart
事件触发时,它会检查可用的放置目标并将它们添加到拖动对象。
我遇到的问题是我在dragstart
事件触发后动态添加了drop目标,因此用户无法使用这些动态添加的drop目标。
示例:
http://jsfiddle.net/blowsie/36AJq/
问题:
如何更新拖动以允许在拖动开始后删除已添加到dom的元素?
答案 0 :(得分:5)
您可以使用此代码段。
重要的功能是:$.event.special.drop.locate();
在chrome / safari / firefox / ie9上测试过并且似乎有效。
<强>更新强>
对于重叠事件,请查看以下代码是否有效。我在匿名函数中设置它只是为了避免任何全局变量。 想法是使用event的currentTarget属性来检查相同的元素是否触发相同的事件。我只是为了测试而在newdrop元素上设置了一个id。
(function () {
var $body = $("body"),
newdrops = [],
currentTarget = {},
ondragstart = function () {
$(this).css('opacity', .75);
}, ondrag = function (ev, dd) {
$(this).css({
top: dd.offsetY,
left: dd.offsetX
});
}, ondragend = function () {
$(this).css('opacity', '');
for (var i = 0, z = newdrops.length; i < z; i++)
$(newdrops[i]).off('dropstart drop dropend').removeClass('tempdrop');
newdrops = [];
}, ondropstart = function (e) {
if (currentTarget.dropstart === e.currentTarget) return;
currentTarget.dropstart = e.currentTarget;
currentTarget.dropend = null;
console.log('start::' + e.currentTarget.id)
$(this).addClass("active");
}, ondrop = function () {
$(this).toggleClass("dropped");
}, ondropend = function (e) {
if (currentTarget.dropend === e.currentTarget) return;
currentTarget.dropend = e.currentTarget;
currentTarget.dropstart = null;
console.log('end::' + e.currentTarget.id)
$(this).removeClass("active");
};
$body.on("dragstart", ".drag", ondragstart)
.on("drag", ".drag", ondrag)
.on("dragend", ".drag", ondragend)
.on("dropstart", ".drop", ondropstart)
.on("drop", ".drop", ondrop)
.on("dropend", ".drop", ondropend);
var cnt = 0;
setInterval(function () {
var dataDroppables = $body.data('dragdata')['interactions'] ? $body.data('dragdata')['interactions'][0]['droppable'] : [];
var $newDrop = $('<div class="drop tempdrop" id="' + cnt + '">Drop</div>');
cnt++;
$("#dropWrap").append($newDrop);
var offset = $newDrop.offset();
var dropdata = {
active: [],
anyactive: 0,
elem: $newDrop[0],
index: $('.drop').length,
location: {
bottom: offset.top + $newDrop.height(),
elem: $newDrop[0],
height: $newDrop.height(),
left: offset.left,
right: offset.left + $newDrop.width,
top: offset.top,
width: $newDrop.width
},
related: 0,
winner: 0
};
$newDrop.data('dropdata', dropdata);
dataDroppables.push($newDrop[0]);
$newDrop.on("dropstart", ondropstart)
.on("drop", ondrop)
.on("dropend", ondropend);
$.event.special.drop.locate($newDrop[0], dropdata.index);
newdrops.push($newDrop[0]);
}, 1000);
})();
答案 1 :(得分:1)
我无法使用jquery.event.drag和jquery.event.drop进行此操作,但我确实使用了原生HTML5事件:
解决方案是绑定函数中的放置目标上的事件,并调用它来更新绑定。我怀疑你可以使用类似的主体使用jquery.event.drag和jquery.event.drop。如果我可以让那些工作,我会更新我的答案。
这是JS:
$(function() {
var bind_targets = function() {
$(".drop").on({
dragenter: function() {
$(this).addClass("active");
return true;
},
dragleave: function() {
$(this).removeClass("active");
},
drop: function() {
$(this).toggleClass("dropped");
}
});
};
$("div[draggable]").on({
dragstart: function(evt) {
evt.originalEvent.dataTransfer.setData('Text', 'data');
},
dragend: function(evt) {
$('.active.drop').removeClass('active');
}
});
setInterval(function () {
$("#dropWrap").append('<div class="drop">Drop</div>');
// Do something here to update the dd.available
bind_targets();
}, 1000)
});
答案 2 :(得分:0)
你做不到。在dragstart
上,可能的删除区域是从DOM计算的,在dragend
之前无法编辑。即使经常重新绑定.on()
(演示:http://jsfiddle.net/36AJq/84/)也无法提供所需的效果。
我解决了这个问题的方式略有不同。 (演示:http://jsfiddle.net/36AJq/87/)
<div>
开始。opacity: 0
以使其不可见,并width: 0
使其无法在隐藏时获得dropend
。setInterval
每1000毫秒显示下一个隐藏的div($('.drop:not(.visible)').first()
)。JS:
$("body")
.on("dragstart", ".drag", function () {
$(this).css('opacity', .75);
})
.on("drag", ".drag", function (ev, dd) {
$(this).css({
top: dd.offsetY,
left: dd.offsetX
});
})
.on("dragend", ".drag", function () {
$(this).css('opacity', '');
})
.on("dropstart", ".drop", function () {
$(this).addClass("active");
})
.on("drop", ".drop", function () {
$(this).toggleClass("dropped");
})
.on("dropend", ".drop", function () {
$(this).removeClass("active");
});
setInterval(function () {
$('.drop:not(.visible)').first()
.addClass('visible').removeClass('hidden');
}, 1000)
答案 3 :(得分:-1)
答案 4 :(得分:-2)
为什么不将所有div放入页面并将其可见性设置为隐藏?然后使用setInterval()每秒更改每个人的可见性。