1

I have 2 boxes and a picture. The user can drag the picture between the 2 boxes. How do I tell which box the picture is dragged from? I tried looking at the parent element of the picture but that didn't work because the HTML doesn't change, I guess.

<!DOCTYPE html>
<html>

<head>
  <script>
    function allowDrop(ev) {
      ev.preventDefault();
    }

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

    function dropone(ev) {
      ev.preventDefault();
      var data = ev.dataTransfer.getData("text");
      var nodeCopy = document.getElementById(data).cloneNode(true);
      nodeCopy.id = "newId";
      nodeCopy.setAttribute("style", "position:absolute; left:" + ev.x + "px;top:" + ev.y + "px;transform:translate(-" + nodeCopy.width / 2 + "px,-" + nodeCopy.height / 2 + "px)");
      ev.target.appendChild(nodeCopy);
    }

    function drop(ev) {
      if (document.getElementById('picture').parentElement.id == 'bluebox') {
        alert("YOU DRAGGED FROM THE BLUE BOX!");
        ev.preventDefault();
        var data = ev.dataTransfer.getData("text");
        var nodeCopy = document.getElementById(data).cloneNode(true);
        nodeCopy.id = "newId";
        nodeCopy.setAttribute("style", "position:absolute; left:" + ev.x + "px;top:" + ev.y + "px;transform:translate(-" + nodeCopy.width / 2 + "px,-" + nodeCopy.height / 2 + "px)");
        ev.target.appendChild(nodeCopy);
      } else if (document.getElementById('picture').parentElement.id == 'redbox') {
        alert("YOU DRAGGED FROM THE RED BOX!");
        ev.preventDefault();
        var data = ev.dataTransfer.getData("text");
        var nodeCopy = document.getElementById(data).cloneNode(true);
        nodeCopy.id = "newId";
        nodeCopy.setAttribute("style", "position:absolute; left:" + ev.x + "px;top:" + ev.y + "px;transform:translate(-" + nodeCopy.width / 2 + "px,-" + nodeCopy.height / 2 + "px)");
        ev.target.appendChild(nodeCopy);
      }
    }
  </script>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    
    .box {
      display: block;
      height: 300px;
      width: 300px;
      background-color: red;
    }
    
    .boxtwo {
      display: block;
      height: 300px;
      width: 300px;
      background-color: lightblue;
    }
  </style>
</head>

<body>

  <span id="redbox" class="box" ondrop="drop(event)" ondragover="allowDrop(event)"></span>

  <br />

  <span id="bluebox" class="boxtwo" ondrop="drop(event)" ondragover="allowDrop(event)">
      <div id="picture" ondrop="drop(event)">
          <img src="https://www.w3schools.com/html/img_w3slogo.gif" draggable="true" ondragstart="drag(event)" id="drag1" width="88" height="31">
      </div>
    </span>
</body>

</html>

Or, view a TryIt here: https://www.w3schools.com/code/tryit.asp?filename=GBYRXSX3L0PP

Thanks in advance!

johannchopin
  • 13,720
  • 10
  • 55
  • 101
  • Premis I could think of would be: define the boxes spaces (x and y coordinates) then add an event listener for 'click' on the document and if through event bubbling both the image and box where both clicked you could use that to say from which box it had been moved. Im guessing the issue is that it always says its being dragged from the blue box right? that wasn't clear but thats what im seeing from some testing – Wally Feb 16 '20 at 18:16

2 Answers2

0

In your code you are running:

var nodeCopy = document.getElementById(data).cloneNode(true);

I believe that this is copying the root element (the reference of the original) and duplicating its original details which would mean that all elements have originated from the blue box -

Instead of using clone node maybe try

1)

creating an element div and appending it to the location provided by the user input by the drag and drop

2)

writing strick html for the element and using incertAdjacenthtml https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML

Have a look at this post on the subject of creating original cloned elements from a source element

How do I correctly clone a JavaScript object?

I hope this helps you debug!

Wally

Wally
  • 705
  • 1
  • 9
  • 24
  • Follow the documentation from MDN - create the element store it in say a let x = element. Then once the user has dragged the image to that location (which you are getting already thorugh your function) when inserting the element via the insertAdjacentHtml - make its style possition match the co-ordicates. Best guess on how to impliment it but im sure there are other ways to approach the situation – Wally Feb 17 '20 at 18:39
0

On drop() function you get the a parameter ev. You can get from this one the id of the target using ev.toElement.id. You can so just check wich id has the target:

<!DOCTYPE html>
<html>

<head>
  <script>
    function allowDrop(ev) {
      ev.preventDefault();
    }

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

    function dropone(ev) {
      ev.preventDefault();
      var data = ev.dataTransfer.getData("text");
      var nodeCopy = document.getElementById(data).cloneNode(true);
      nodeCopy.id = "newId";
      nodeCopy.setAttribute("style", "position:absolute; left:" + ev.x + "px;top:" + ev.y + "px;transform:translate(-" + nodeCopy.width / 2 + "px,-" + nodeCopy.height / 2 + "px)");
      ev.target.appendChild(nodeCopy);
    }

    function drop(ev) {
      if (ev.toElement.id == 'redbox') {    // <-- Check the id
        alert("YOU DRAGGED FROM THE BLUE BOX!");
        ev.preventDefault();
        var data = ev.dataTransfer.getData("text");
        var nodeCopy = document.getElementById(data).cloneNode(true);
        nodeCopy.id = "newId";
        nodeCopy.setAttribute("style", "position:absolute; left:" + ev.x + "px;top:" + ev.y + "px;transform:translate(-" + nodeCopy.width / 2 + "px,-" + nodeCopy.height / 2 + "px)");
        ev.target.appendChild(nodeCopy);
      } else if (ev.toElement.id == 'bluebox') {  // <-- Check the id
        alert("YOU DRAGGED FROM THE RED BOX!");
        ev.preventDefault();
        var data = ev.dataTransfer.getData("text");
        var nodeCopy = document.getElementById(data).cloneNode(true);
        nodeCopy.id = "newId";
        nodeCopy.setAttribute("style", "position:absolute; left:" + ev.x + "px;top:" + ev.y + "px;transform:translate(-" + nodeCopy.width / 2 + "px,-" + nodeCopy.height / 2 + "px)");
        ev.target.appendChild(nodeCopy);
      }
    }
  </script>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    
    .box {
      display: block;
      height: 300px;
      width: 300px;
      background-color: red;
    }
    
    .boxtwo {
      display: block;
      height: 300px;
      width: 300px;
      background-color: lightblue;
    }
  </style>
</head>

<body>

  <span id="redbox" class="box" ondrop="drop(event)" ondragover="allowDrop(event)"></span>

  <br />

  <span id="bluebox" class="boxtwo" ondrop="drop(event)" ondragover="allowDrop(event)">
  <div id="picture" ondrop="drop(event)">
      <img src="https://www.w3schools.com/html/img_w3slogo.gif" draggable="true" ondragstart="drag(event)" id="drag1" width="88" height="31">
  </div>
</span>
</body>

</html>
johannchopin
  • 13,720
  • 10
  • 55
  • 101