Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I am trying to drag and drop an image on a div. The image does not get get dragged onto the div and gives the following error

Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.draganddrop.html:20 dropdraganddrop.html:26 ondrop
  <!DOCTYPE HTML>
        <meta charset="utf-8">
        <title>Creativity Dashboard</title>
        <!-- Required CSS -->
        <link href="css/movingboxes.css" rel="stylesheet">
        <link href="css/compare.css" rel="stylesheet">
        <!--[if lt IE 9]>
           <link href="css/movingboxes-ie.css" rel="stylesheet" media="screen">
        <![endif]-->
        <!-- Required script -->
        <script src="http://code.jquery.com/jquery-1.8.0.min.js"></script>
        <script src="js/jquery.movingboxes.js"></script>
        <!-- Demo only -->
        <link href="demo/demo.css" rel="stylesheet">
        <script src="demo/demo.js"></script>
        <script>
           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));
        </script>
        <style>
           /* Overall & panel width defined using css in MovingBoxes version 2.2.2+ */
           #slider-one {
              width: 1003px;
           #slider-one>li {
              width: 150px;
        </style>
     </head>
        <div class="wrapper">
           <!-- Slider #1 -->
           <ul id="slider-one">
              <li><img id="drag1" src="demo/1.jpg" draggable="true"
                 ondragstart="drag(event)" alt="picture"></li>
              <li><img id="drag2" src="demo/2.jpg" draggable="true"
                 ondragstart="drag(event)" alt="picture"></li>
              <li><img id="drag3" src="demo/3.jpg" draggable="true"
                 ondragstart="drag(event)" alt="picture"></li>
              <li><img id="drag5" src="demo/4.jpg" draggable="true"
                 ondragstart="drag(event)" alt="picture"></li>
              <li><img id="drag6" src="demo/5.jpg" draggable="true"
                 ondragstart="drag(event)" alt="picture"></li>
              <li><img id="drag7" src="demo/6.jpg" draggable="true"
                 ondragstart="drag(event)" alt="picture" id="astronaut"></li>
              <li><img id="drag8" src="demo/7.jpg" draggable="true"
                 ondragstart="drag(event)" alt="picture"></li>
           <!-- end Slider #1 -->
           <div id="dragAnddrop" ondrop="drop(event)"
              ondragover="allowDrop(event)" style="width: 12em; height: 12em">
           <div class="left">
              <img id="drag" draggable="true" ondragstart="drag(event)"
                 src="images/startingImage.jpg" style="width: 12em;" alt="picture">
           <div class="middle ">
              <img id="image3" src="images/startingImage.jpg" class="image-size"
                 alt="picture" draggable="true" ondragstart="drag(event)"> <img
                 src="images/harvest.jpg" class="image-size" alt="picture">
           <div class="right">
              <img src="images/startingImage.jpg" style="width: 12em;"
                 alt="picture">
     </body>
  </html>
                You use ev.target.appendChild(document.getElementById(data)); but if there is no element with id data then document.getElementById will return null. So ev.target.appendChild(null) will throw.
– Oriol
                Nov 22, 2014 at 16:25
                For those who were searching for an exact answer in one go: Appending HTML using native JavaScript
– Shamiq
                Sep 28, 2022 at 20:06

It's actually a simple answer.

Your function is returning a string rather than the div node. appendChild can only append a node.

For example, if you try to appendChild the string:

var z = '<p>test satu dua tiga</p>'; // is a string 
document.body.appendChild(z);

The above code will never work. What will work is:

var z = document.createElement('p'); // is a node
z.innerHTML = 'test satu dua tiga';
document.body.appendChild(z);
                Bad question but do we have to remove the newly created element after appending? I am asking this as in some situations where there will be a loop and inside loo there will be append child options. Will there be any memory issue or more garbage elements created in dom ?
– Kurkula
                Nov 20, 2017 at 19:26

This can happen if you accidentally are not dragging the element that does have an id assigned (for example you are dragging the surrounding element). In that case the ID is empty and the function drag() is assigning an empty value which is then passed to drop() and fails there.

Try assigning the ids to all of your elements, including the tds, divs, or whatever is around your draggable element.

For future readers who want to use React 17 new react/jsx-transform to just use jsx syntax without using any hook:

  • uninstall react via npm uninstall react

  • keep your react-dom

  • update babel config. Add:

    plugins: [
      ['@babel/plugin-transform-react-jsx', { runtime: 'automatic' }],
    

    note: you can replace @babel/preset-react with @babel/plugin-transform-react-jsx, as indicated in this code.

  • change your syntax to

    ReactDOM.render(<Comp/>, document.getElementById('fuc_'))
    
  •