HTML5 + Javascript拖放

时间:2013-04-09 12:36:11

标签: javascript html5 drag-and-drop draggable droppable

我的问题基于这个例子,但有一些差异.. http://jsfiddle.net/raad/SSxdB/15/

我使用的菜单有3-4个类别,每个类别有4个项目.. 所以我想将一个元素拖放到指定的div ..和指定的元素,从菜单列表中隐藏(我已经完成了这个)但是也能够撤消它(已经弄清楚了)并且还,如果我拖动另一个元素放在指定的div上,已经删除了另一个元素,第一个要恢复的元素,而新的元素占据了它的位置。 这是我有问题..这是代码..

    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");
        var draggedOrNewNodeId = "dragged-"+data;
        var theNode = document.getElementById(data);
        var draggedNode = document.getElementById(draggedOrNewNodeId);
        if (draggedNode != null) { ev.target.removeChild(draggedNode); }
        var nodeCopy = theNode.cloneNode(true);
        nodeCopy.id = draggedOrNewNodeId;
        nodeCopy.setAttribute("class", "dragged");
        nodeCopy.setAttribute("draggable", "false");
        document.getElementById(data).style.display = "none";
        remove_id = draggedOrNewNodeId +  "_remove";
        nodeCopy.innerHTML="<span class='undo' id='" + remove_id + "'>x</span>";
        ev.target.appendChild(nodeCopy);

        var remove = document.getElementsByClassName("undo").length;
            for (i=0; i<remove; i++) {
            var nodeToBeRemoved = /_remove$/;
            var nodeToBeReplaced = /dragged-/;
            deletedNode = remove_id.replace(nodeToBeRemoved, "");
            restoredNode = deletedNode.replace(nodeToBeReplaced, "");
                document.getElementsByClassName("undo")[i].onclick = function() {
                    elem = document.getElementById(deletedNode);deleted
                    elem.parentNode.removeChild(elem);
                    document.getElementById(restoredNode).style.display = "block";
                }
            }
    }

这就是“导致”问题分离的部分,因为如果已经放置了2个或者移动div,它们就会全部消失......另一个问题是,如果我将它插入allowDrop( ev)函数,它实际上删除了以前的元素,并且在drop上放置了新的元素..但是当元素超过div时它会删除它们...但是当我想要在drop下时这样做。所以当我移动它时删除功能的一段代码,它确实删除了之前输入的元素,但它“消失”了新的元素......以及...无法分辨为什么会发生这种情况.. 我还想建议替换temp_node = document.getElementsByClassName(“dragged”)[0];通过更具体的(可能来自指定的ev.target的子节点?

        tempNodeCheck = hasClass(ev.target, "dragged"); 
        if (tempNodeCheck) {
                var nodeToBeReplacedcopy = /dragged-/;
                tempParentNode = ev.target.parentNode;
                temp_node = document.getElementsByClassName("dragged")[0];
                temp_node1 = document.getElementsByClassName("dragged")[0].id;
                restoredNode = temp_node1.replace(nodeToBeReplacedcopy, "");
                temp_node1.parentNode.removeChild(temp_node1);
                document.getElementById(restoredNode).style.display = "block";

html看起来像这样

<div id="drag1" draggable="true" ondragstart="drag(event)"></div>
<div id="drag2" draggable="true" ondragstart="drag(event)"></div>
<div id="drag3" draggable="true" ondragstart="drag(event)"></div>
<div id="drag4" draggable="true" ondragstart="drag(event)"></div>

<div class="droparea" id="drop1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="droparea" id="drop2" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="droparea" id="drop3" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="droparea" id="drop4" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="droparea" id="drop5" ondrop="drop(event)" ondragover="allowDrop(event)"></div>

这里是jsfiddle排序的http://jsfiddle.net/q5FAq/3/ 但我也注意到,如果删除的div包含内部的sth,它不会与div一起“移动”..(目前在我尝试过的时候我已经在每个div上使用了背景图像,因此它并不明显。

1 个答案:

答案 0 :(得分:0)

这里有解决方案.. 为什么div正在消失,当行动是要取代droparea上现有的div?

因为ev.target会“看到”作为目标,droparea中的现有div。 例如......

当一个元素被放置在放置区域的第一个位置时,ev.target就是div id=drop1(如果选择放在那里)

BUT 当另一个元素被放置在先前已经放置在droparea中的元素之上时,ev.target将是dragged-drag1但是因为代码,应该删除该div,因此最近删除了div也消失了......

所以在

行下
 ev.target.appendChild(nodeCopy);

被这个块替换

        tempNodeCheck = hasClass(ev.target, "dragged");
        if (tempNodeCheck) {
                var nodeToBeReplacedcopy = /dragged-/;
                tempParentNode = ev.target.parentNode;
                temp_node_class = tempParentNode.getElementsByClassName("dragged")[0];
                temp_node_id = temp_node_class.id;
                remove_node = document.getElementById(temp_node_id);
                restoredNode = temp_node_id.replace(nodeToBeReplacedcopy, "");  
                remove_node.parentNode.removeChild(remove_node);
                document.getElementById(restoredNode).style.display = "block";
                tempParentNode.appendChild(nodeCopy);
        }
        else {
        ev.target.appendChild(nodeCopy);
        }