将放置区域限制为某些可拖动元素
Restrict drop areas to some draggable elements
我一直在做一个需要 HTML5
拖放的项目,但我在 atm 上遇到了一些可能很容易实现但我似乎找不到解决方案的问题。
基本上我有一些可拖动的元素和一些放置区域。因为用一个工作示例来解释总是更容易,所以我把这个简单化了 JSFIDDLE
现在您可以将任何元素拖动到任何放置区域或根据需要将它们移出,但我想要实现的是使橙色框仅放置在任何绿色区域(并忽略蓝色的……如果你把它放在那里,让它回到原来的位置),红色的盒子就进入蓝色的盒子(忽略绿色的)。
任何人都可以帮助我或提示我解决此问题的方法吗?
function DragOver(ev) {
ev.preventDefault();
}
function Drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function Drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
var elemens = document.querySelectorAll('.draggable');
[].forEach.call(elemens, function(elem) {
elem.addEventListener('dragover', DragOver, false);
elem.addEventListener('drop', Drop, false);
});
#divContenedor {
width: 950px;
height: 500px;
}
#div1,
#div2,
#div3 {
width: 350px;
height: 70px;
border: 1px solid #aaaaaa;
background-color: green;
}
#div4 {
width: 350px;
height: 70px;
border: 1px solid #aaaaaa;
background-color: blue;
}
<p>
Drag&drop testing</p>
<div id="divContenedor" class="draggable" style="background-color: yellow; width: 100%; float: left; position: relative;">
<div id="drag1" draggable="true" ondragstart="Drag(event)" style="width: 336px; height: 69px; background-color: orange; cursor: move;">1</div>
<div id="drag2" draggable="true" ondragstart="Drag(event)" style="width: 336px; height: 69px; background-color: orange; cursor: move;">2</div>
<div id="drag3" draggable="true" ondragstart="Drag(event)" style="width: 336px; height: 69px; background-color: red; cursor: move;">3</div>
</div>
<div style="position: absolute; top: 100px; left: 500px;">
<div id="div1" class="draggable" ></div>
<br />
<div id="div2" class="draggable" ></div>
<br />
<div id="div3" class="draggable" ></div>
<br />
<div id="div4" class="draggable" ></div>
</div>
使用@Amen 解决方案更新JSFIDDLE。
您可以使用 data
属性逻辑并进行以下 3 项简单修改来实现
1) 添加到 draggable
元素属性 data-appendto="green"
或 blue
2) 添加到 div
元素,您可以在其中添加可拖动元素 data-boxtype="red"
或 blue
3) 在 Drop(ev)
函数中,您可以检查 document.getElementById(data)
和 ev.target
数据属性值是否匹配,然后允许删除。可以用js .getAttribute('data-attribute')
function
获取元素data-attribute
if(ev.target.getAttribute('data-boxtype') ==
document.getElementById(data).getAttribute('data-appendto')){
ev.target.appendChild(document.getElementById(data));
}
Armen 回答得好,但如果您想处理 dragover 事件的访问权限,请添加另一个简单地表示是的属性。
如您所见,我的 JavaScript 模块对象中有 4 个方法,它们都是从拖放元素事件中调用的。
第 1 步。OnDragStart 事件通过将 data-ts-allowdrop 属性更改为 "Yes"(默认为否)为所有匹配其放置元素查询的潜在目标设置阶段。假设一个元素将接受超过 1 个源,我执行包含查询来查找元素而不是完全匹配
第 2 步。在接收元素上拖动时,其 DragOver 事件将检查其 "data-ts-allowdrop" 属性以查看其是否已设置为 true 或 "Yes"。如果是这样,那么它会运行 preventsDefault 并且允许放置并由 OnDrop 方法处理,该方法继续关闭 "data-ts-allowdrop" 属性。
第 3 步。同时使用 onEnd 将 "data-ts-allowdrop" 设置为 No,以防拖动事件被取消。
<div id="divName" draggable="true" ondragstart="tsjDragnDrop.setSource(event);" data-ts-drag-allow-source="admin" tabindex="1" ><span >Item to Drag</span><img alt="an icon" src="~/images/anImage.png" /></div>
<li ondragover="tsjDragnDrop.allowTarget(event);" ondragleave="tsjDragnDrop.onLeave(event)" ondrop="tsjDragnDrop.onDrop(event)" data-ts-drag-allow-target="admin" data-ts-allowdrop="No" >Drop Target in a list item</li>
var DraggnApi = {
allowTarget: function (event) {
var source = $(event.currentTarget).attr("data-ts-allowdrop");
$(event.currentTarget).addClass("ts-dragover");
if (source === "Yes") {
event.preventDefault();
}
},
onLeave: function (event) {
$(event.currentTarget).removeClass("ts-dragover");
},
onDrop: function (event) {
event.preventDefault();
var source = $(event.currentTarget).removeClass("ts-dragover");
$(event.currentTarget).attr("data-ts-allowdrop", "No");
},
onEnd: function (event) {
$(event.currentTarget).attr("data-ts-allowdrop", "No");
},
setSource: function(e)
{
e.dataTransfer.setData("text", "SomeText");
var source = $(event.currentTarget).attr("data-ts-drag-allow-source");
if ($("li[data-ts-drag-allow-target]").attr("data-ts-drag-allow-target").indexOf(source) > -1) {
$("li[data-ts-drag-allow-target*='" + source + "']").attr("data-ts-allowdrop", "Yes");
}
}
}
我一直在做一个需要 HTML5
拖放的项目,但我在 atm 上遇到了一些可能很容易实现但我似乎找不到解决方案的问题。
基本上我有一些可拖动的元素和一些放置区域。因为用一个工作示例来解释总是更容易,所以我把这个简单化了 JSFIDDLE
现在您可以将任何元素拖动到任何放置区域或根据需要将它们移出,但我想要实现的是使橙色框仅放置在任何绿色区域(并忽略蓝色的……如果你把它放在那里,让它回到原来的位置),红色的盒子就进入蓝色的盒子(忽略绿色的)。
任何人都可以帮助我或提示我解决此问题的方法吗?
function DragOver(ev) {
ev.preventDefault();
}
function Drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function Drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
var elemens = document.querySelectorAll('.draggable');
[].forEach.call(elemens, function(elem) {
elem.addEventListener('dragover', DragOver, false);
elem.addEventListener('drop', Drop, false);
});
#divContenedor {
width: 950px;
height: 500px;
}
#div1,
#div2,
#div3 {
width: 350px;
height: 70px;
border: 1px solid #aaaaaa;
background-color: green;
}
#div4 {
width: 350px;
height: 70px;
border: 1px solid #aaaaaa;
background-color: blue;
}
<p>
Drag&drop testing</p>
<div id="divContenedor" class="draggable" style="background-color: yellow; width: 100%; float: left; position: relative;">
<div id="drag1" draggable="true" ondragstart="Drag(event)" style="width: 336px; height: 69px; background-color: orange; cursor: move;">1</div>
<div id="drag2" draggable="true" ondragstart="Drag(event)" style="width: 336px; height: 69px; background-color: orange; cursor: move;">2</div>
<div id="drag3" draggable="true" ondragstart="Drag(event)" style="width: 336px; height: 69px; background-color: red; cursor: move;">3</div>
</div>
<div style="position: absolute; top: 100px; left: 500px;">
<div id="div1" class="draggable" ></div>
<br />
<div id="div2" class="draggable" ></div>
<br />
<div id="div3" class="draggable" ></div>
<br />
<div id="div4" class="draggable" ></div>
</div>
使用@Amen 解决方案更新JSFIDDLE。
您可以使用 data
属性逻辑并进行以下 3 项简单修改来实现
1) 添加到 draggable
元素属性 data-appendto="green"
或 blue
2) 添加到 div
元素,您可以在其中添加可拖动元素 data-boxtype="red"
或 blue
3) 在 Drop(ev)
函数中,您可以检查 document.getElementById(data)
和 ev.target
数据属性值是否匹配,然后允许删除。可以用js .getAttribute('data-attribute')
function
data-attribute
if(ev.target.getAttribute('data-boxtype') ==
document.getElementById(data).getAttribute('data-appendto')){
ev.target.appendChild(document.getElementById(data));
}
Armen 回答得好,但如果您想处理 dragover 事件的访问权限,请添加另一个简单地表示是的属性。
如您所见,我的 JavaScript 模块对象中有 4 个方法,它们都是从拖放元素事件中调用的。
第 1 步。OnDragStart 事件通过将 data-ts-allowdrop 属性更改为 "Yes"(默认为否)为所有匹配其放置元素查询的潜在目标设置阶段。假设一个元素将接受超过 1 个源,我执行包含查询来查找元素而不是完全匹配
第 2 步。在接收元素上拖动时,其 DragOver 事件将检查其 "data-ts-allowdrop" 属性以查看其是否已设置为 true 或 "Yes"。如果是这样,那么它会运行 preventsDefault 并且允许放置并由 OnDrop 方法处理,该方法继续关闭 "data-ts-allowdrop" 属性。
第 3 步。同时使用 onEnd 将 "data-ts-allowdrop" 设置为 No,以防拖动事件被取消。
<div id="divName" draggable="true" ondragstart="tsjDragnDrop.setSource(event);" data-ts-drag-allow-source="admin" tabindex="1" ><span >Item to Drag</span><img alt="an icon" src="~/images/anImage.png" /></div>
<li ondragover="tsjDragnDrop.allowTarget(event);" ondragleave="tsjDragnDrop.onLeave(event)" ondrop="tsjDragnDrop.onDrop(event)" data-ts-drag-allow-target="admin" data-ts-allowdrop="No" >Drop Target in a list item</li>
var DraggnApi = {
allowTarget: function (event) {
var source = $(event.currentTarget).attr("data-ts-allowdrop");
$(event.currentTarget).addClass("ts-dragover");
if (source === "Yes") {
event.preventDefault();
}
},
onLeave: function (event) {
$(event.currentTarget).removeClass("ts-dragover");
},
onDrop: function (event) {
event.preventDefault();
var source = $(event.currentTarget).removeClass("ts-dragover");
$(event.currentTarget).attr("data-ts-allowdrop", "No");
},
onEnd: function (event) {
$(event.currentTarget).attr("data-ts-allowdrop", "No");
},
setSource: function(e)
{
e.dataTransfer.setData("text", "SomeText");
var source = $(event.currentTarget).attr("data-ts-drag-allow-source");
if ($("li[data-ts-drag-allow-target]").attr("data-ts-drag-allow-target").indexOf(source) > -1) {
$("li[data-ts-drag-allow-target*='" + source + "']").attr("data-ts-allowdrop", "Yes");
}
}
}