拖放 - DataTransfer 对象

Drag & Drop - DataTransfer object

我正在构建一个简单的拖放上传器,我想知道为什么当我 console.log(e) (DragEvent) 并查看 DragEvent.dataTransfer.files 它显示为空,但是...如果我 console.log(e.dataTransfer.files) 它会显示删除的文件。

//代码

<!DOCTYPE html>
<html>
<head>
<script>
document.addEventListener("DOMContentLoaded", init);
function init(){
    var dropbox = document.getElementById('dropbox');
    dropbox.addEventListener('dragover', drag.over);
    dropbox.addEventListener('drop', drag.drop);
}
var drag = {
    "over": function(e){
        e.preventDefault();
    },
    "drop": function(e){
        e.preventDefault();
        console.log(e); //NO FILES SHOWN
        console.log(e.dataTransfer.files); //FILES in FileList Object
    }   
};  
</script>
<style>
body{
    margin: 0 !important;
    height: 100vh;
    width: 100vw;
    display: flex;
    justify-content: center;
}
#dropbox{
    height: 400px;
    width: 400px;
    align-self: center;
    background-color: #0089C4;
    border-radius: .3em;
    border: 1px dashed black;
    -webkit-box-shadow: 0px 2px 7px rgba(0, 0, 0, 0.40);
    box-shadow: 0px 2px 7px rgba(0, 0, 0, 0.40);
}
</style>
</head>
<body>
    <div id="dropbox"></div>    
</body> 
</html>

拖动数据存储有不同的模式,具体取决于您访问它的时间:

  • dragstart 事件中它处于 read/write 模式。
  • drop 事件中,它处于 只读 模式。
  • 并且在所有其他事件中,它处于 受保护 模式。

    Protected 模式是这样定义的:

Protected mode

For all other events. The formats and kinds in the drag data store list of items representing dragged data can be enumerated, but the data itself is unavailable and no new data can be added.

看这里:https://html.spec.whatwg.org/multipage/interaction.html#the-drag-data-store

这意味着当您在控制台中访问不在 dropdragstart 事件中的 dataTransfer 对象时,它处于 protected 模式,阻止您访问数据。

您可以查看 fileList,因为当 dataTransfer 可读时,您在 drop 事件上记录了 fileList。但是,如果您登录 e.dataTransfere,您将无法访问任何数据。

您可以在这里测试,即使在 dragover 上您也无法访问 dataTransfer 中的内容:

document.querySelector('#droppable').ondragover = function(e) {
  console.log('on dragover files are', e.dataTransfer.files)
  e.preventDefault();
}

document.querySelector('#droppable').ondrop = function(e) {
  console.log('on drop files are', e.dataTransfer.files)
  e.preventDefault();
}
<div id=droppable>Drop a file</div>