JavaScript拖放 - 防止元素拖放到另一个可拖放的元素中

javascript drag and drop - prevent elements from dropping into another droppable element

本文关键字:拖放 元素 另一个 JavaScript      更新时间:2023-09-26

标题是这样说的 - 如果我将第一个元素放在"井"中,第二个可放置元素可以放在第一个元素中。我还需要防止几个元素掉入同一个"井"中。HTML是这样的:

 <div class="container-fluid">
    <div class="row">
        <table class="table">
            <tbody>
                <tr>
                    <td>Word 3</td>
                    <td><div class="well" style="max-width: 200px;" id="div3" ondrop="drop(event)" ondragover="allowDrop(event)"></div></td>
                    <td><div class="btn btn-primary" id="drag1" draggable="true" ondragstart="drag(event)" width="336" height="69">Move 1</div></td>
                </tr>
                <tr>
                    <td>Word 2</td>
                    <td><div class="well" style="max-width: 200px;" id="div2" ondrop="drop(event)" ondragover="allowDrop(event)"></div></td>
                    <td><div class="btn btn-primary" id="drag2" draggable="true" ondragstart="drag(event)" width="336" height="69">Move 2</div></td>
                </tr>
                <tr>
                    <td>Word 1</td>
                    <td><div class="well" style="max-width: 200px;" id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div></td>
                    <td><div class="btn btn-primary" id="drag3" draggable="true" ondragstart="drag(event)" width="336" height="69">Move 3</div></td>
                </tr>
            </tbody>
        </table>
    </div>
</div>

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));
    stop();
}

问题是当你把你的元素放在其中一个井或其内容(!)上的任何位置时,drop()函数将被调用。但是,该函数中的ev.target将指向您要丢弃的实际元素,该元素可能不是井,而是您之前丢弃的另一个元素。

因此,您需要检查内部drop() ev.target是否是有效的投放目标。

一个非常简单的测试:

function drop(ev) {
    ev.preventDefault();
    if (ev.target.id.match("drag"))
      return;
    var data = ev.dataTransfer.getData("text");
    ev.target.appendChild(document.getElementById(data));
    stop();
}

其他信息

这是由于所谓的事件冒泡。

当发生类似drop的事件时,它会发送到目标。然后,当有侦听器为该事件注册时,目标可以决定捕获它,例如通过 ondrop 属性。如果没有侦听器来捕获事件,则会将其发送到元素父级。

该父级

现在决定是捕获事件还是将其发送给自己的父级,依此类推......

但是,ev.target仍将指向事件最初发送到的元素。

为此使用 Jquery UI,因为实现非常简单。

要定义可放置对象:

$( ".selector" ).droppable({
    accept: ".special" // .selector will only allow elements to be dropped on it that the class .special
});

要更新它:

$( ".selector" ).droppable( "option", "accept", ".special2" );

要使元素可拖动:

// Allow elements with class .selector to be dragged
$( ".selector" ).draggable( "enable" );

要更新它:

// Disable dragging for elements with class .selector
$( ".selector" ).draggable( "disable" );

在您的情况下,您可以启用所有三个元素:

$( "#drag1, #drag2, #drag3" ).draggable( "enable" );
// Make #drag1 one droppable, accepts #drag2
$( "#drag1" ).droppable({
    accept: "#drag2"
});
// So so on so forth...

这几行可以用您想要影响的任何类和元素来重现。它比具有所有属性和函数的JavaScript版本容易得多。

确保包括:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>

文档:

可滴落

可拖动

教程

如果您有任何问题,请发表评论