JavaScript-如何使多个div在网站上可拖动和移动

时间:2018-07-18 19:26:50

标签: javascript drag-and-drop draggable

我希望在我的网站上有多个div,以便在整个网站上(或至少在找到它的容器中)可拖动和移动。

我想澄清一下,我在网络和Stackoverflow上进行了多次搜索,但是所有这些搜索都通过使用jQuery或其他一些库来给出答案。我想用一种纯JavaScript的方式在网站上移动多个div(希望所有功能都只有一个)。

我正在做的项目是使用HTML和JS进行拖放操作,我在容器“ x”(其中有图像)中有4个div,并在另一个容器“ y”中将这些div拖放到该容器“ y”,但是如果我将它们全部拖到那里,则第一个div设置为左上角,其余设置为它们的下一个(如果我将其显示设置为inline-block,则彼此相邻)。因此,我想使这些div可在我拖入的容器“ y”上移动以将其移动到需要的位置。 (它们也可以调整大小)。

拖放式JavaScript和HTML代码(不包括CSS和一些不必要的HTML代码)是这样的:

function allowDrop(ev) {
    ev.preventDefault();
}

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

function drop(ev) {
    ev.preventDefault();
    var data = ev.dataTransfer.getData("text");
    ev.target.appendChild(document.getElementById(data));
}
<div id="images-container" ondrop="drop(event)" ondragover="allowDrop(event)">

      <div class="resize" style="background: url('images/photo-1.jpg') center no-repeat; background-size: cover; background-position: center center;" id="drag1" draggable="true" ondragstart="drag(event)">
      </div>
      <div class="resize" style="background: url('images/photo-2.jpg') center no-repeat; background-size: cover; background-position: center center;" id="drag2" draggable="true" ondragstart="drag(event)">
      </div>
      <div class="resize" style="background: url('images/photo-3.jpg') center no-repeat; background-size: cover; background-position: center center;" id="drag3" draggable="true" ondragstart="drag(event)">
      </div>
      <div class="resize" style="background: url('images/photo-4.jpg') center no-repeat; background-size: cover; background-position: center center;" id="drag4" draggable="true" ondragstart="drag(event)">
      </div>

 </div>

 <div id="gallery" ondrop="drop(event)" ondragover="allowDrop(event)"></div>

我检查了W3schools的this文章,但是它仅使用一个div元素,因为它是用ID构建的,但是我可以用这段代码对多个div和我猜到的类使用它吗?如果还有另一种方法,尽管使用纯JavaScript,我也会很高兴听到一些建议。

谢谢。

2 个答案:

答案 0 :(得分:1)

这对我有用。没有使用JQuery。

我在彼此之上产生4个div,但是它们可以拖动。 单击div时,其边框会亮起,可以拖动它。拖动的div移动到其他div的前面。因为它看起来很有趣,所以我使用画布在div之间绘制了曲线。

<!doctype html>
<html>
    <head>
        <style>
            div {
            position: absolute;
            top: 0;
            height: 60px;
            width: 100px;
            background: #15a5ed;
            text-align: center;
            line-height: 60px;
            border-radius: 15px 15px 15px 15px;
            }
        </style>
    </head>
    <body>
        <canvas id="canvas" class="canvas"></canvas>
        <div id="div1">Me</div>
        <div id="div2">You</div>
        <div id="div3">Us</div>
        <div id="div4">Them</div>
        <script>
            divs = document.getElementsByTagName("div");
            for (div of divs) div.onmousedown = onMouseDown;
            
            document.onmousemove = onMouseMove;
            document.onmouseup   = onMouseUp;
            
            canvas.width = window.innerWidth - 20;
            canvas.height = window.innerHeight - 20;
            
            var the_moving_div = ''; 
            var the_last_mouse_position = { x:0, y:0 };
            
            drawConnectors();
            
            function onMouseDown(e) {
                e.preventDefault();
                the_moving_div            = e.target.id;      // remember which div has been selected 
                the_last_mouse_position.x = e.clientX;        // remember where the mouse was when it was clicked
                the_last_mouse_position.y = e.clientY;
                e.target.style.border = "2px solid blue";     // highlight the border of the div
            
                var divs = document.getElementsByTagName("div");
                e.target.style.zIndex = divs.length;          // put this div  on top
                var i = 1; for (div of divs) if (div.id != the_moving_div) div.style.zIndex = i++;   // put all other divs behind the selected one
            }
            
            function onMouseMove(e) {
                e.preventDefault();
                if (the_moving_div == "") return;
                var d = document.getElementById(the_moving_div);
                d.style.left = d.offsetLeft + e.clientX - the_last_mouse_position.x + "px";     // move the div by however much the mouse moved
                d.style.top  = d.offsetTop  + e.clientY - the_last_mouse_position.y + "px";
                the_last_mouse_position.x = e.clientX;                                          // remember where the mouse is now
                the_last_mouse_position.y = e.clientY;
                drawConnectors();
            }
            
            function onMouseUp(e) {
                e.preventDefault();
                if (the_moving_div == "") return;
                document.getElementById(the_moving_div).style.border = "none";             // hide the border again
                the_moving_div = "";
            }
            
            function drawConnectors() {
                var canvas = document.getElementById('canvas');
                var ctx = canvas.getContext('2d');
                ctx.clearRect(0,0,canvas.width,canvas.height);
                ctx.beginPath();
                ctx.strokeStyle="#15a5ed";
                ctx.lineWidth=3;
                for (div1 of divs) for (div2 of divs) {
                    if (div1 == div2) continue;
                    ctx.moveTo(div1.offsetLeft + div1.clientWidth/2, div1.offsetTop + div1.clientHeight/2);
                    ctx.bezierCurveTo(div1.offsetLeft, div1.offsetTop, 
                                      div2.offsetLeft, div2.offsetTop, 
                                      div2.offsetLeft + div2.clientWidth/2, div2.offsetTop + div2.clientHeight/2);
                    ctx.stroke();                   
                }
            }
        </script>
    </body>
</html>

答案 1 :(得分:0)

我想您现在可能已经对此进行了排序。我将在这里将其发布给寻找答案的像我这样的人。我认为w3Schools示例也仅适用于单个元素。实际上,仅通过在每个元素上调用函数就可以在多个元素上工作。

var draggableElements = document.getElementsByClassName("draggable");

for(var i = 0; i < draggableElements.length; i++){
    dragElement(draggableElements[i]);
}

function dragElement(elmnt) {
    var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
    if (document.getElementById(elmnt.id + "header")) {
        document.getElementById(elmnt.id + "header").onmousedown = dragMouseDown;
    } else {
        elmnt.onmousedown = dragMouseDown;
    }
    function dragMouseDown(e) {
        e = e || window.event;
        pos3 = parseInt(e.clientX);
        pos4 = parseInt(e.clientY);
        document.onmouseup = closeDragElement;
        document.onmousemove = elementDrag;
        return false;
    }

    function elementDrag(e) {
        e = e || window.event;
        pos1 = pos3 - parseInt(e.clientX);
        pos2 = pos4 - parseInt(e.clientY);
        pos3 = parseInt(e.clientX);
        pos4 = parseInt(e.clientY);
        elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
        console.log(elmnt.offsetTop)
        elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
    }

    function closeDragElement() {
        document.onmouseup = null;
        document.onmousemove = null;
    }
}

现在起初这给了我奇怪的结果。当我移动鼠标时,我的div只朝一个方向移动,如果div上有边距,则会使计算混乱。因此,要么不使用边距,要么不编辑代码以适合他们。

链接到原始的W3Schools tut:https://www.w3schools.com/howto/howto_js_draggable.asp