8

Ipotesi: Una pagina web HTML locale/Javascript che ha accesso a file: //Come aggiungere un file in un oggetto dataTransfer già esistente utilizzando Javascript

All'inizio di un peso per un elemento HTML trascinabile, nel funzione di gestore eventi dragStart(e), come posso aggiungere un oggetto File in modo che venga riconosciuto come un file e finito nell'elenco dataTransfer.files?

Es:

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]); 
    } 
} 

In particolare, ha bisogno di lavorare su Chrome/Chromium. E, possiamo presumere che il file esista nell'unità locale. Fondamentalmente, voglio che gli stessi dati siano disponibili quando un file viene trascinato da Windows Explorer a una pagina HTML su un elemento che è trascinabile.

So che questo esiste in Chrome:

e.originalEvent.dataTransfer.setData("DownloadURL", fileType + ":" + name + ":" + filePath); 

che scarica il file. Ma questo non è quello che voglio, perché voglio presumere che si tratta di un file esistente e che è necessario accedere al file originale.

+0

Dubito che questo può essere fatto. Se capisco correttamente, stai essenzialmente chiedendo al browser di caricare il file di qualcuno senza che avvenga il trasferimento del file. Non riesco a vedere i browser che permettano che ciò accada, sarebbe un difetto di sicurezza –

+0

Se si è in grado di ottenere file in 'var file = getSomeFileObjFromSomewhere();' quale è lo scopo di impostare l'oggetto file su 'event.dataTransfer'? Cosa stai cercando di ottenere? – guest271314

+0

@KScandrett: l'oggetto File deve essere generato da elementi già accessibili a Javascript (compresi gli oggetti File generati esplicitamente dall'interazione dell'utente con un input di file) –

risposta

0

È possibile utilizzare l'approccio inviato da @kol a Simulate drop file event

Cioè, dobbiamo passare un argomento a OnDrop, che

  • ha un campo dataTransfer con un sottocampo files array, che contiene il metodo selezionato File e
  • a preventDefault (una funzione senza corpo lo farà).

regolato seguente per fissare .addEventListener("drop") a drop elemento a dragstart evento, con File oggetti passati ad una funzione legata con Function.prototype.bind() che restituisce l'oggetto appropriato sopra descritto, con once:true passato al terzo parametro .addEventListener(), chiamare drop evento al massimo una volta per ogni evento dragstart in cui gli oggetti File sono accessibili o creati.

FileList oggetto è di sola lettura, un Array viene utilizzata per memorizzare File oggetto alla dataTransfer.files proprietà all'interno di un javascript oggetto pianura gestori di eventi.

Nota: L'interfaccia FileList dovrebbe essere considerato "a rischio" dal momento che la tendenza generale sulla piattaforma web è quello di sostituire tali interfacce con l'oggetto Array piattaforma ECMAScript [ECMA-262]. In particolare, ciò significa che la sintassi del tipo filelist.item(0) è a rischio; è improbabile che la maggior parte dell'uso programmatico di FileList sia influenzato dall'eventuale migrazione a un tipo Array.

Se event.dataTransfer.files a dragstart evento contiene File oggetti, iterare FileList e spingere ciascun oggetto File a files matrice.

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

+0

Grazie, questo sembra come il progresso! Sembra funzionare se visto dall'evento dragstart, ma gli elementi/file dataTransfer non sembrano persistere fino all'evento drop. O sto facendo qualcosa di sbagliato lì? http://plnkr.co/edit/H5gfm82JZGRuEuDIM7WM?p=preview –

+0

@FabioBeltramini Nota, la domanda in realtà non menziona l'evento 'drop'. – guest271314

+0

@FabioBeltramini http://plnkr.co/edit/mw5DbPIKBhw3G5t29EiJ?p=preview – guest271314

Problemi correlati