JavaScript addEventListener 不适用于 onDrop、onDragOver 或 onDragStart

Posted

技术标签:

【中文标题】JavaScript addEventListener 不适用于 onDrop、onDragOver 或 onDragStart【英文标题】:JavaScript addEventListener not working with onDrop, onDragOver, or onDragStart 【发布时间】:2017-07-10 14:48:58 【问题描述】:

我正在用 javascript 创建一个简单的图片益智游戏,并尝试实现 html5 拖放 API。如果我将 ondragstart、ondragover 或 ondrop 事件添加到元素(即作为属性),它会起作用。

但是,因为在同一类别中有很多不同的元素,我需要添加事件侦听器(如果我尝试用更多块拼图,它只会增加),我正在使用 addEventListener 添加事件.但是,如果我这样做,它不起作用。我已经在 Chrome 和 Firefox 中进行了测试。作为记录,我真的很想看看我是否可以使用 HTML5 Drag and Drop API 而不是 jQuery。

以下是相关的 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);

这是随附的 HTML。请注意,为了证明正常事件有效但 addEventListener 无效的事实,我在第一个拼图块和第一个拼图槽中添加了一个正常事件。那些工作正常,但其余的却不行。

<!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>

有史以来第一个 Stack Overflow 问题,希望我没有做任何太愚蠢的事情;)

【问题讨论】:

"作为记录,我真的很想看看我是否可以使用 HTML5 Drag and Drop API 而不是使用 jQuery 来实现这一点。"你确实意识到你不需要 jquery 来做这个...... 我知道,这实际上是重点。只是每当拖放出现时,似乎都提到了 jQuery,我宁愿只使用 HTML 和纯 JavaScript。对不起,我没有说清楚! '^^ 【参考方案1】:

为 img 元素添加一些高度和宽度。

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

这解决了问题

【讨论】:

谢谢,我非常感谢您的快速回答,但我认为您可能错过了重点。带有“ondragstart=”dragPiece(event)”的图像已经可以工作了,我只是将它作为一个演示包含在内。我的目标是使用 addEventListener 使图像工作没有“内联”事件。使用这种技术,它仍然不起作用. 对不起,如果我混淆了。【参考方案2】:

我知道这已经有好几年了,但我现在也在与draggable 合作,这篇文章中关于与addEventListener 一起使用它的信息很少,所以也许它可以帮助某人。

请注意,拖动事件在addEventListener APIHTML attribute 中具有不同的名称(其他events 也是如此)。在你的情况下:

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

应该是

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

dragOver 相同;应该是dragover

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

【讨论】:

以上是关于JavaScript addEventListener 不适用于 onDrop、onDragOver 或 onDragStart的主要内容,如果未能解决你的问题,请参考以下文章

Javascript 的addEventListener()及attachEvent()区别分析

在Class里面的Javascript ES6 addEventListener

多个 addEventListener 如何在 JavaScript 中工作?

无法读取 null 的属性“addEventListener”(JavaScript Sails 应用程序)

您可以使用 addEventListener (javascript) 区分多个变量吗?

Javascript 获得“点击”元素 addEventListener