如何使用Javascript将文件添加到现有的dataTransfer对象中

时间:2014-06-30 18:55:08

标签: javascript file drag-and-drop data-transfer data-transfer-objects

假设:可以访问file://

的本地HTML / Javascript网页

在可拖动HTML元素的拖动开始时,在事件处理函数dragStart(e)中,如何添加File对象以使其被识别为文件并最终在{{1}中} list?

例如:

dataTransfer.files

具体来说,它需要适用于Chrome / Chromium。并且,我们可以假设该文件存在于本地驱动器上。基本上,当文件从Windows资源管理器拖动到可放置的元素上的HTML页面时,我想要相同的数据。

我知道这存在于Chrome中:

function dragStart(e){
    var file = getSomeFileObjFromSomewhere();
    e.originalEvent.dataTransfer.effectAllowed = "all";
    e.originalEvent.dataTransfer.setData("file", file);

    console.log("\nFiles:");
    i = 0;
    var files = e.originalEvent.dataTransfer.files,
    len = files.length;
    for (; i < len; i++) {
        console.log("\nIndex: " + i + "\nFilename: " + files[i].name);
        console.log("Type: " + files[i].type);
        console.log("Size: " + files[i].size + " bytes");
        console.dir(files[i]);
    }
}

下载文件。但这不是我想要的,因为我想假设这是一个现有文件,并且必须访问原始文件。

1 个答案:

答案 0 :(得分:3)

您可以使用@kol在Simulate drop file event

发布的方法
  

也就是说,我们必须将参数传递给ondrop,

     
      
  • dataTransfer字段带有files数组子字段,其中包含所选的File
  •   
  • 一个preventDefault方法(没有正文的函数会这样做)。
  •   

在下面进行了调整,以便在.addEventListener("drop")事件中将drop附加到dragstart元素,并将File个对象传递给带有Function.prototype.bind()的绑定函数,该函数返回相应的对象如上所述,once:true将第三个参数传递给.addEventListener(),为访问或创建drop个对象的每个dragstart事件最多调用一次File个事件

FileList对象是只读的,Array用于在事件处理程序的普通File对象中的dataTransfer.files属性中存储javascript对象。 / p>

  

注意:FileList界面应视为“有风险”   因为Web平台的总体趋势是取代这样的   与ECMAScript Array中的 [ECMA-262]平台对象接口。特别是,这意味着排序的语法   filelist.item(0)面临风险;大多数其他程序化使用   FileList不太可能受到最终迁移到的影响   Array类型。

如果event.dataTransfer.files事件dragstart包含File个对象,请迭代FileList并将每个File对象推送到files数组。

var drag = document.getElementById("drag")
var drop = document.getElementById("drop")

function handleDrop(evt) {
  evt.preventDefault();
  console.log(evt.dataTransfer.files);
}

function getSomeFileObjFromSomewhere() {
  var data = ["abc", "def"];
  var files = [];
  for (var i = 0; i < data.length; i++) {
    files.push(new File([data[i]], data[i] + ".text", {
      type: "text/plain",
      lastModified: new Date().getTime()
    }));
  }
  return files
}

function dataTransferFileObject(files) {
  return {
    preventDefault: function() {},
    dataTransfer: {
      files: Array.isArray(files) ? files : [files]
    }
  }
}

drag.addEventListener("dragstart", function dragStart(e) {

  var files = getSomeFileObjFromSomewhere();
  e.dataTransfer.effectAllowed = "all";

  console.log("\nFiles:");
  
  for (let i = 0; i < files.length; i++) {
    var {name, size, type} = files[i];
    console.log("\nFilename: " + name);
    console.log("Type: " + type);
    console.log("Size: " + size + " bytes");
  }
  // if `e.dataTransfer.files`, push `File` objects dragged
  // to `files` array
  if (e.dataTransfer.files) {
    for (let file of e.dataTransfer.files) {
      files.push(file);
    }
  }
  
  drop.addEventListener("drop"
  , handleDrop.bind(drop, dataTransferFileObject(files))
  , {once: true});

});

drop.addEventListener("dragover", function(evt) {
  evt.preventDefault()
});
div {
  width: 50px;
  height: 50px;
  padding: 10px;
  margin: 10px;
}

div:nth-child(1) {
  border: 2px dotted blue;
}

div:nth-child(2) {
  border: 2px dotted green;
}
<div draggable="true" id="drag">drag</div>
<div droppable="true" id="drop" webkitdropzone="webkitdropzone">drop</div>

plnkr http://plnkr.co/edit/ihQqs4t2zOg2XhIuNwal?p=preview