Javascript 在jquery.event.drag中触发dragstart后更新可用的放置目标
概述: 我有一个使用和的页面。 我需要能够拖放到不断添加到dom中的元素上,即使在拖动开始之后也是如此Javascript 在jquery.event.drag中触发dragstart后更新可用的放置目标,javascript,jquery,drag-and-drop,Javascript,Jquery,Drag And Drop,概述: 我有一个使用和的页面。 我需要能够拖放到不断添加到dom中的元素上,即使在拖动开始之后也是如此 问题: 当触发dragstart事件时,它会检查可用的拖放目标,并将它们添加到拖动对象中 我遇到的问题是,在触发dragstart事件后,我正在动态添加放置目标,因此用户无法放置到这些动态添加的放置目标上 示例: 问题: 如何更新拖动以允许在开始拖动后拖放已添加到dom中的元素?启用。为什么不将所有div放入页面并将其可见性设置为隐藏?然后使用setInterval()每秒更改每个对象
问题: 当触发
dragstart
事件时,它会检查可用的拖放目标,并将它们添加到拖动对象中
我遇到的问题是,在触发dragstart
事件后,我正在动态添加放置目标,因此用户无法放置到这些动态添加的放置目标上
示例:
问题:
如何更新拖动以允许在开始拖动后拖放已添加到dom中的元素?启用。为什么不将所有div放入页面并将其可见性设置为隐藏?然后使用setInterval()每秒更改每个对象的可见性。您不能。在
dragstart
上,可能的放置区域是从DOM计算出来的,在dragend
之前无法编辑。即使不断地重新绑定()(演示:)上的.on(),也无法提供所需的效果
我解决这个问题的方式有点不同。(演示:)
从HTML中的每个
开始
应用opacity:0
使其不可见,应用width:0
使其在隐藏时不会出现dropend
使用setInterval
显示下一个隐藏的div($('.drop:not(.visible))。第一个()
)每1000毫秒显示一次
JS:
我无法使用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)
});
$(函数(){
var bind_targets=函数(){
美元(“.drop”)。在({
dragenter:function(){
$(此).addClass(“活动”);
返回true;
},
dragleave:function(){
$(此).removeClass(“活动”);
},
drop:function(){
$(此).toggleClass(“已删除”);
}
});
};
$(“div[draggable]”)。在({
dragstart:函数(evt){
evt.originalEvent.dataTransfer.setData('Text','data');
},
dragend:功能(evt){
$('.active.drop').removeClass('active');
}
});
setInterval(函数(){
$(“#dropWrap”).append('Drop');
//在此处执行某些操作以更新可用的dd
绑定_目标();
}, 1000)
});
您可以使用此代码段
重要的函数是:$.event.special.drop.locate()代码>
在chrome/safari/firefox/ie9上进行了测试,似乎有效
更新
对于重叠事件,请查看以下代码是否有效。我在匿名函数中设置它只是为了避免任何全局变量。
其思想是使用事件的currentTarget属性来检查是否不是相同的元素触发了相同的事件。我在newdrop元素上设置了一个id,只是为了在这里进行测试
(函数(){
变量$body=$(“body”),
newdrops=[],
currentTarget={},
ondragstart=函数(){
$(this.css('opacity',.75);
},ondrag=函数(ev,dd){
$(this.css)({
顶部:dd.offsetY,
左:dd.offsetX
});
},ondragend=函数(){
$(this.css('opacity','');
for(var i=0,z=newdrops.length;i$(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)
});
(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);
})();