2012-05-30 10 views
7

Prima di avere un'esperienza JavaScript limitata, ti consiglierò. JavaScript/HTML5/jQuery Caricamento con trascinamento della selezione - "Tipo non rilevato Errore: impossibile leggere la proprietà" file "di non definito"


Attualmente, ho il codice JavaScript:

$('#xhr-filebox').bind({ 
    "dragover": HandleDragEvent, 
    "dragleave": HandleDragEvent, 
    "drop": HandleDropEvent 
}); 

function HandleDropEvent(e){ 
    var files = e.target.files || e.dataTransfer.files; 
    UploadFile(files[0]); 
} 

(è omesso un codice, ma aggiungerà più se richiesta)

... e il codice HTML:

<div class="filebox" id="xhr-filebox"> 
    <p id="xhr-action">...or click me to pick one.</p> 
</div> 

Tuttavia, quando trascino un file, la console Chrome JS dice:

Uncaught TypeError: Cannot read property 'files' of undefined

Può tuttavia ottenere l'oggetto FileList durante la lettura da un input di file.

Curiosamente, quando accedo l'argomento evento (console.log (e)), si registra come f.event, mentre in uno script simile di mine, esso registra come MouseEvent (screenshot: http://i.stack.imgur.com/3krcT.png)

A differenza della funzione bind() in jQuery, utilizza la funzione addEventListener() di un oggetto DOM restituito da getElementById(), IE è puro JavaScript. Ho provato questo metodo ma non succede nulla di nuovo.

+0

potresti per favore guardare la mia domanda http://stackoverflow.com/questions/27898745/how-to-get-the-filename-in-javascript-from-input-file-tag-in-ie-browser. .. grazie – Hitesh

risposta

14

Se files non esiste su e.target, siete alla ricerca di un files su e.dataTransfer   — ma se non c'è alcuna proprietà dataTransfer su e (e non sembra di essere nel vostro screenshot) si tenta di dereference undefined, con conseguente errore.

Cambierei il codice per:

function HandleDropEvent(e){ 
    var files = e.target.files || (e.dataTransfer && e.dataTransfer.files); 
    if (files) { 
     UploadFile(files[0]); 
    } 
    else { 
     // Perhaps some kind of message here 
    } 
} 

questo modo, se e.target.files non esiste e e.dataTransferanche non esiste, si otterrà files essendo undefined, piuttosto che un errore .


L'oggetto evento fornito da jQuery viene creato e normalizzato da jQuery. Poiché sappiamo che e.dataTransfer non esiste su quell'oggetto evento (dal tuo screenshot), suppongo che non sia una delle proprietà jQuery copia dall'oggetto evento originale. Va bene, però, perché jQuery ci dà accesso all'evento originale tramite e.originalEvent. Quindi mi piacerebbe provare:

function HandleDropEvent(e){ 
    var dt = e.dataTransfer || (e.originalEvent && e.originalEvent.dataTransfer); 
    var files = e.target.files || (dt && dt.files); 
    if (files) { 
     UploadFile(files[0]); 
    } 
    else { 
     // Perhaps some kind of message here 
    } 
} 

che cattura files da e.target se è lì che è, o dall'oggetto dataTransfer ovunque ci troviamo (su e, o e.originalEvent).

+0

I ** so ** esiste l'oggetto file, è solo che penso che Chrome non stia passando alla funzione. – svbnet

+0

@Joe: Il mio punto era che il tuo codice è dereferenziamento 'indefinito', motivo per cui ottieni l'errore. Ho aggiunto un pensiero: ho il sospetto che tu stia cercando "e.originalEvent.dataTransfer.files". –

+0

Che ha funzionato in modo eccellente; Grazie!!! – svbnet

0

ero stato utilizzando il seguente codice per l'ultimo parecchi anni:

var files = e.target.files || 
(e.dataTransfer ? e.dataTransfer.files : e.originalEvent.dataTransfer.files); 

Tuttavia, ho recentemente incontrato un problema con Chrome dove e.target.files era lì, ma con una lunghezza di 0 che ha causato che i file siano vuoti anche se dataTransfer aveva i file rilasciati.

Così, ho dovuto usare un controllo leggermente diversa:

var files = e.target.files; 
if (!files || files.length === 0) 
    files = (e.dataTransfer ? e.dataTransfer.files : .originalEvent.dataTransfer.files); 

hopefuly questo può aiutare qualcun altro.

Problemi correlati