通过HTML的文件API ,Firefox、Chrome等浏览器已经支持从操作系统直接拖拽文件,并上传到服务器。
相对于使用了十多年的HTML表单,这是一个革命性的进步。虽然IE的落后让很多开发者还在观望中,但是Gmail邮箱的附件拖拽功能已经给部分用户带来了极大的方便,而需要大量上传文件的CMS(内容管理系统)也将会从中受益。
让我们看一下Firefox 是如何使用拖拽上传功能的:
首先提供一个区域来放置文件
Html代码
1
|
<div name=
"image"
id=
"dropbox"
style=
"min-width:300px;min-height:100px;border:3px dashed silver;"
></div>
|
然后监听拖拽过程中的dragenter、dragleave、drop等事件
Js代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
document.addEventListener(
"dragenter"
,
function
(e){
dropbox.style.borderColor =
'gray'
;
},
false
);
document.addEventListener(
"dragleave"
,
function
(e){
dropbox.style.borderColor =
'silver'
;
},
false
);
dropbox.addEventListener(
"dragenter"
,
function
(e){
dropbox.style.borderColor =
'gray'
;
dropbox.style.backgroundColor =
'white'
;
},
false
);
dropbox.addEventListener(
"dragleave"
,
function
(e){
dropbox.style.backgroundColor =
'transparent'
;
},
false
);
dropbox.addEventListener(
"dragenter"
,
function
(e){
e.stopPropagation();
e.preventDefault();
},
false
);
dropbox.addEventListener(
"dragover"
,
function
(e){
e.stopPropagation();
e.preventDefault();
},
false
);
dropbox.addEventListener(
"drop"
,
function
(e){
e.stopPropagation();
e.preventDefault();
handleFiles(e.dataTransfer.files);
submit.disabled =
false
;
},
false
);
|
其中最主要的是drop事件中用handleFiles()依次处理所有文件
1
2
3
4
5
6
|
handleFiles =
function
(files) {
for
(
var
i = 0; i < files.length; i++) {
var
file = files[i];
}
}
|
对于图片类型的文件可以直接读取内容,显示预览图
1
2
3
4
5
6
7
8
9
10
11
12
|
if
(!file.type.match(/image*/)) {
continue
;
}
var
img = document.createElement(
"img"
);
img.classList.add(
"obj"
);
img.file = file;
preview.appendChild(img);
var
reader =
new
FileReader();
reader.onload = (
function
(aImg) {
return
function
(e) { aImg.src = e.target.result; }; })(img);
reader.readAsDataURL(file);
|
接下来就是核心功能:ajax上传。首先新建一个XHR请求
1
2
|
var
xhr =
new
XMLHttpRequest();
xhr.open(
'post'
,
'/file/upload'
,
true
);
|
监听上传进度和完成事件
width="0" height="0" src="http://blog.sina.com.cn/s/blog_6ab1c8fe0100lm8h.html">
1
2
3
4
5
6
7
8
9
10
|
xhr.upload.addEventListener(
"progress"
,
function
(e) {
if
(e.lengthComputable) {
var
percentage = Math.round((e.loaded * 100) / e.total);
img.style.opacity = 1-percentage/100.0;
}
},
false
);
xhr.upload.addEventListener(
"load"
,
function
(e){
},
false
);
|
最后把数据模拟成multipart/form-data的格式上传
1
2
3
4
5
6
7
8
9
10
11
|
xhr.setRequestHeader(
"Content-Type"
,
"multipart/form-data, boundary="
+boundary);
// simulate a file MIME POST request.
xhr.setRequestHeader(
"Content-Length"
, fileSize);
var
body =
''
;
body +=
"--"
+ boundary +
"\r\n"
;
body +=
"Content-Disposition: form-data; name=\""
+dropbox.getAttribute(
'name'
)+
"\"; filename=\""
+ fileName +
"\"\r\n"
;
body +=
"Content-Type: "
+fileType+
"\r\n\r\n"
;
body += fileData +
"\r\n"
;
body +=
"--"
+ boundary +
"--\r\n"
;
xhr.sendAsBinary(body);
|