javascript拖放 - 防止元素掉入另一个droppable元素

时间:2016-04-21 12:24:16

标签: javascript jquery html css

标题说 - 如果我将fisrt元素放在"井"中,第二个可放置元素可以放在第一个元素内。此外,我需要防止几个元素落入相同的"井"。 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();
}

2 个答案:

答案 0 :(得分:3)

问题是,当您将元素放在其中一个井或其内容(!)上的任何位置时,将调用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之类的事件发生时,它会发送给目标。然后,当有一个监听器注册该事件时,目标可以决定捕获它,例如: G。通过ondrop属性。如果没有侦听器捕获事件,则将其发送给父元素。

该父母现在决定是否抓住该事件或将其发送给自己的父母等等......

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

答案 1 :(得分:1)

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

定义一个droppable:

$( ".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>

文档:

Droppable

Draggable

Tutorial

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