TJD
TJD

Reputation: 29

JavaScript addEventListener not working with onDrop, onDragOver, or onDragStart

I'm creating a simple picture puzzle game in JavaScript and am trying to implement the HTML5 Drag and Drop API. If I add an ondragstart, ondragover, or ondrop event to an element (i.e. as an attribute), it works.

However, because there are quite a few different elements in the same category I need to add event listeners to (which will only increase if I try to make a puzzle with more pieces), I'm using addEventListener to add the events. However, if I do this, it doesn't work. I've tested in Chrome and Firefox. For the record, I would really like to see if I can get this working with the HTML5 Drag and Drop API rather than with jQuery.

Here's the relevant JavaScript:

var piecesOnPage = document.querySelectorAll("#pieces img");
var puzzleSlots = document.getElementsByTagName("td");

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

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

function dropPiece(ev) {
    ev.preventDefault();
    var data = ev.dataTransfer.getData("text");
    ev.target.appendChild(document.getElementById(data));
}

function createEventListeners() {
    if (piecesOnPage[0].addEventListener) {
       for (i = 0; i < piecesOnPage.length; i++) {
        piecesOnPage[i].addEventListener("dragStart", dragPiece, false);
      }
    } else if (piecesOnPage[0].attachEvent) {
        for (i = 0; i < piecesOnPage.length; i++) {
        piecesOnPage[i].attachEvent("onDragStart", dragPiece);
       }
    }

   if (puzzleSlots[0].addEventListener) {
       for (i = 0; i < puzzleSlots.length; i++) {
        puzzleSlots[i].addEventListener("drop", dropPiece, false);
   }
    } else if (puzzleSlots[0].attachEvent) {
       for (i = 0; i < puzzleSlots.length; i++) {
       puzzleSlots[i].attachEvent("onDrop", dropPiece);
      }
    }

    if (puzzleSlots[0].addEventListener) {
       for (i = 0; i < puzzleSlots.length; i++) {
        puzzleSlots[i].addEventListener("dragOver", enableDrop, false);
       }
    } else if (puzzleSlots[0].attachEvent) {
        for (i = 0; i < puzzleSlots.length; i++) {
        puzzleSlots[i].attachEvent("onDragOver", enableDrop);
       }
    }
}

if (window.addEventListener) {
   window.addEventListener("load", createEventListeners, false);
} else if (window.attachEvent) {
   window.attachEvent("onload", createEventListeners);
}

Here's the accompanying HTML. Note that, in order to demonstrate the fact that normal events work but addEventListener doesn't, I've added a normal event to the first puzzle piece and the first puzzle slot. Those work fine, but the rest don't.

<!DOCTYPE html>
<html lang="en">
<meta charset="utf-8">
<head>
<title>Puzzles</title>
<style>
    table {
    border:1px #000000 solid;
    border-collapse:collapse;
    float:right;
    margin:10px;
}

td {
    padding:0;
    line-height:0;
    height:96px;
    width:157px;
}
</style>
</head>

<body>
    <table class="puzzleboard">
        <thead></thead>
        <tbody>
            <tr><td id="space1" ondrop="dropPiece(event)" ondragover="enableDrop(event)"></td><td id="space2"></td><td id="space3"></td></tr>
            <tr><td id="space4"></td><td id="space5"></td><td id="space6"></td></tr>
            <tr><td id="space7"></td><td id="space8"></td><td id="space9"></td></tr>
        </tbody>
    </table>
    <div id="pieces">
        <img id="img1" draggable="true" ondragstart="dragPiece(event)" src="2-2.jpeg"><img id="img2" draggable="true" src="1-2.jpeg"><img id="img3" draggable="true" src="2-1.jpeg"><br>
        <img id="img4" draggable="true" src="0-2.jpeg"><img id="img5" draggable="true" src="1-0.jpeg"><img id="img6" draggable="true" src="0-1.jpeg"><br>
        <img id="img7" draggable="true" src="1-1.jpeg"><img id="img8" draggable="true" src="2-0.jpeg"><img id="img9" draggable="true" src="0-0.jpeg"><br>
    </div>
<script src="final-so.js"></script>
</body>
</html>

First Stack Overflow question ever, hope I didn't do anything TOO stupid ;)

Upvotes: 0

Views: 2713

Answers (2)

w0l1w00d
w0l1w00d

Reputation: 31

I know it's been some years, but I'm working with draggable now too and there's little info on this post about using it alongside addEventListener so maybe it can help somebody.

Be aware that the drag events have different names in the addEventListener API and in HTML attribute (this is true for other events too). In your case:

piecesOnPage[i].addEventListener("dragStart", dragPiece, false);

Should be

piecesOnPage[i].addEventListener("dragstart", dragPiece, false);

Same for dragOver; it should be dragover

Documentation: https://developer.mozilla.org/en-US/docs/Web/API/Document/dragstart_event

Upvotes: 1

Able Johnson
Able Johnson

Reputation: 571

Add some height and width to the img element .

<img id="img1" draggable="true" ondragstart="dragPiece(event)" src="2-2.jpeg" height="100" width="100">

this solved the issue

Upvotes: 1

Related Questions