子元素允许拖放

Zer*_*ras 5 html javascript html5 drag-and-drop

我在html5中拖放有一个奇怪的问题.

面板A有一个可以拖动的元素类型列表.面板B是拖动元素的位置.面板C和D是您可以拖动元素的其他位置,您可以在面板B,C和D之间拖动和重新排列元素.

我的问题是我能够拖动一个元素并将其放在其中一个面板内的另一个元素的内部,我不希望用户能够做到这一点.这些面板的子元素没有附加任何类型的javascript或与拖动相关的属性,但它们当前允许将元素拖入其中.

我已经尝试附加"ondrop ='return false;'"和"ondragover ='return false;'",但两者都没有奏效.

当然有一种方法可以关闭元素上的'允许拖入'属性?

这是我的代码:

<div id="elem-002" draggable="true" ondragstart="drag(event)">content</div>
Run Code Online (Sandbox Code Playgroud)

主要小组:

<div id="panel-b" ondrop="drop(event)" ondragover="allowDrop(event)">
  <div id="elem-001" draggable="true" ondragstart="drag(event)">content</div>
</div>
Run Code Online (Sandbox Code Playgroud)

JS:

function allowDrop(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));
}
Run Code Online (Sandbox Code Playgroud)

换句话说:我能够将我的"elem-002"直接拖到"elem-001"中,这是一个已被拖入的元素.这导致了我不想发生的元素嵌套.我怎么能阻止这个?

小智 11

基本上你必须设置正确ev.dataTransfer.dropEffectallowDrop.对于你的draggable元素应该是"none"(不允许删除),以及其他所有元素(或允许删除的任何其他元素)"all"

进一步阅读dropEffect

实例:

window.allowDrop = function(ev) {
    ev.preventDefault();
    if (ev.target.getAttribute("draggable") == "true")
        ev.dataTransfer.dropEffect = "none"; // dropping is not allowed
    else
        ev.dataTransfer.dropEffect = "all"; // drop it like it's hot
};

window.drag = function(ev) {
    ev.dataTransfer.setData("id", ev.target.id);
};

window.drop = function(ev) {
    ev.preventDefault();
    var id = ev.dataTransfer.getData("id");

    var dragged = document.getElementById(id);
    ev.target.appendChild(dragged);
    dragged.className += " dropped";
};
Run Code Online (Sandbox Code Playgroud)
.drag {
    display: inline-block;
    padding: 5px;
    background: rgba(0, 0, 0, 0.2);
    margin: 2px;
}

.dropzone {
    background: #ccc;
    padding: 5px;
    margin-top: 10px;
}
Run Code Online (Sandbox Code Playgroud)
<div id="first" class="drag" draggable="true" ondragstart="drag(event)">1</div>
<div id="second" class="drag" draggable="true" ondragstart="drag(event)">2</div>

<div class="dropzone" ondrop="drop(event)" ondragover="allowDrop(event)"><div id="third" class="drag dropped" draggable="true" ondragstart="drag(event)">3</div></div>
Run Code Online (Sandbox Code Playgroud)


Zer*_*ras 5

我不确定这是否是最好的解决方案,但我确实想出了一些办法。

我将 drop(ev) 更改为:

function drop(ev) {
    ev.preventDefault();

    if (!ev.target.getAttribute("ondrop"))
        return false;

    var data = ev.dataTransfer.getData("Text");
    ev.target.appendChild(document.getElementById(data));
}
Run Code Online (Sandbox Code Playgroud)

此或其变体可防止将任何内容放入未显式定义“ondrop”的元素中。