2012-05-30 27 views
7

Tôi sẽ tư vấn cho bạn trước khi tôi có trải nghiệm JavaScript giới hạn. JavaScript/HTML5/jQuery Tải lên Kéo và Thả - "Loại Lỗi Không bắt buộc: Không thể đọc tệp 'thuộc tính' không xác định"


Hiện nay, tôi có mã JavaScript:

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

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

(một số mã được bỏ qua, nhưng tôi sẽ bổ sung thêm nếu bạn yêu cầu)

... và HTML:

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

Tuy nhiên, khi tôi kéo tệp vào đó, bảng điều khiển Chrome JS nói điều này:

Uncaught TypeError: Cannot read property 'files' of undefined

Tuy nhiên, nó có thể nhận được đối tượng FileList khi đọc từ đầu vào tệp.

Thật kỳ lạ, khi tôi đăng nhập đối số sự kiện (console.log (e)), nó có thể ghi nó như f.event, trong khi trong một kịch bản tương tự của tôi, nó có thể ghi nó như MouseEvent (ảnh chụp màn hình: http://i.stack.imgur.com/3krcT.png)

Không giống như hàm bind() trong jQuery, điều này sử dụng hàm addEventListener() của một đối tượng DOM được trả về bởi getElementById(), IE đây là JavaScript thuần túy. Tôi đã thử phương pháp đó nhưng không có gì mới xảy ra.

+0

bạn có thể xem câu hỏi của tôi http://stackoverflow.com/questions/27898745/how-to-get-the-filename-in-javascript-from-input-file-tag-in-ie-browser. .. cảm ơn – Hitesh

Trả lời

14

Nếu files không tồn tại trên e.target, bạn đang tìm kiếm một files trên e.dataTransfer   — nhưng nếu không có tài sản dataTransfer trên e (và có vẻ không phải là trong ảnh chụp màn hình của bạn), bạn sẽ cố gắng dereference undefined, dẫn đến lỗi này.

Tôi muốn thay đổi mã để:

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

Bằng cách đó, nếu e.target.files không tồn tại và e.dataTransfercũng không tồn tại, bạn sẽ nhận được filesundefined, chứ không phải là một lỗi .


Đối tượng sự kiện mà jQuery cung cấp cho bạn được tạo và chuẩn hóa bởi jQuery. Vì chúng ta biết e.dataTransfer không tồn tại trên đối tượng sự kiện đó (từ ảnh chụp màn hình của bạn), tôi đoán là nó không phải là một trong các thuộc tính jQuery sao chép từ đối tượng sự kiện ban đầu. Đó là okay, mặc dù, bởi vì jQuery cho phép chúng ta truy cập vào sự kiện ban đầu thông qua e.originalEvent. Vì vậy, tôi muốn thử:

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

Đó lấy files từ e.target nếu đó là nó ở đâu, hoặc từ các đối tượng dataTransfer bất cứ nơi nào chúng tôi tìm thấy nó (trên e, hoặc trên e.originalEvent).

+0

Tôi ** biết ** đối tượng tệp tồn tại, chỉ là tôi nghĩ Chrome không chuyển nó sang hàm. – svbnet

+0

@Joe: Quan điểm của tôi là mã của bạn là dereferencing 'undefined', đó là lý do tại sao bạn gặp lỗi. Tôi đã thêm một ý nghĩ: Tôi nghi ngờ bạn đang tìm kiếm 'e.originalEvent.dataTransfer.files'. –

+0

Điều đó đã làm việc xuất sắc; Cảm ơn bạn!!! – svbnet

0

Tôi đã sử dụng đoạn mã sau trong vài năm trở lại đây:

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

Tuy nhiên, tôi vừa mới chạy vào một vấn đề sử dụng Chrome nơi e.target.files đã có nhưng với chiều dài 0 khiến tệp bị trống ngay cả khi dataTransfer đã có các tệp đã bị xóa.

Vì vậy, tôi đã phải sử dụng một tấm séc hơi khác nhau:

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

Hopefuly này có thể giúp người khác.

Các vấn đề liên quan