我正在研究一个文件上传代码,目前仅适用于 Chrome 和 Firefox。它允许用户拖放上传的文件。上传进度显示在网格中。
这是html
<form id="fileUploadForm" action="home/upload" method="post" enctype="multipart/form-data">
<input type="file" id="fileselect" name="files" multiple="multiple" />
<div id="filedrag">Drop files here</div>
<button type="submit" id="submitbutton">Upload Files</button>
</form>
<table class="datatable" data-bind="visible:files().length>0">
<thead>
<tr>
<th>Name</th>
<th>Status</th>
<th>Upload progress</th>
<th>Progress bar</th>
</tr>
</thead>
<tbody data-bind="foreach:files">
<tr>
<td data-bind="text:name"></td>
<td data-bind="text:status"></td>
<td data-bind="text:percentUploaded"></td>
<td>
<progress max="100" data-bind="attr: {value:percentUploaded}"></progress>
<span data-bind="text:$root.files().length"></span></td>
</tr>
</tbody>
</table>
<pre data-bind="text: ko.toJSON($data.files, null, 2)"></pre>
这是JavaScript:
var File = function (f) {
this.name = f.name;
this.type = f.type;
this.size = f.size;
this.lastModified = f.lastModifiedDate.toDateString();
this.status = ko.observable(f.status);
this.percentUploaded = ko.observable(0);
};
var ViewModel = function () {
var self = this,
maxFileSize = 5000000,
onFileSelecting = function (e) {
e.stopPropagation();
e.preventDefault();
e.target.className = (e.type == "dragover" ? "hover" : "");
},
onFileSelected = function (e) {
onFileSelecting(e);// cancel event and hover styling
var files = e.target.files || e.dataTransfer.files;
for (var i = 0, f; f = files[i]; i++) {
var validationResult = validate(f);
f.status = validationResult || 'Uploading';
self.addFile(f);
uploadFile(f);
}
},
validate = function (f) {
if (f.size > maxFileSize)
return 'Too large, should be less than 5MB';
if (f.type.indexOf("text") != 0)
return 'Wrong file type';
},
uploadFile = function (f) {
var file = self.files()[0];
var fd = new FormData();
fd.append("files", f, f.name);
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", function (e) {
file.status("Uploaded " + parseInt(e.loaded / e.total * 100) + "%");
file.percentUploaded(parseInt(e.loaded / e.total * 100));
}, false);
xhr.onreadystatechange = function (e) {
if (xhr.readyState == 4) {
file.status((xhr.status == 200 ? "success" : "failure"));
}
};
xhr.open("POST", $("#fileUploadForm")[0].action, true);
xhr.setRequestHeader("X_FILENAME", file.name);
xhr.send(fd);
};
self.files = ko.observableArray();
self.addFile = function (f) { self.files.unshift(new File(f)); };
$(document).ready(function () {
if (window.File && window.FileList && window.FileReader) {
var fileSelector = $("#fileselect"),
fileDragArea = $("#filedrag"),
submitButton = $("#submitbutton");
fileSelector.change(onFileSelected);
var xhr = new XMLHttpRequest();
if (xhr.upload) {
filedrag.addEventListener("dragover", onFileSelecting, false);
filedrag.addEventListener("dragleave", onFileSelecting, false);
filedrag.addEventListener("drop", onFileSelected, false);
filedrag.style.display = "block";
submitbutton.style.display = "none";
fileSelector.hide();
}
}
});
};
var model = new ViewModel();
ko.applyBindings(model);
当我拖放一组文件时,一切正常。但是,当我拖放另一组时,文件数组会更新,但网格不会显示其他行。
但是,当我取出这段 HTML5 标记时,一切正常:
<progress max="100" data-bind="attr: {value:percentUploaded}"></progress>
我已经创建了小提琴(http://jsfiddle.net/9aJtG/1),但它还有其他问题 - 1)小提琴上的拖放只会打开文件(不知道为什么)2)删除文件被提交,但没有可以与 JSFiddle 表单发布一起使用的服务器端代码
我在另一个例子中尝试过使用进度条,它没有这个问题http://jsfiddle.net/bxfXd/800/
有任何想法吗?
非常感谢!