Gmail和QQ邮箱都实现了在Chrome下的拖拽上传,于是我又查了一些资料终于也实现了Chrome下的拖拽上传。没有看Gmail和QQ邮箱写信页的源码,但是在http://stackoverflow.com/questions/2657653/drag-and-drop-file-upload-in-google-chrome-chromium这里找到了一些解决的方案,因为Chrome不支持FileReader,所以无法通过模拟文件上传的方式来用Ajax上传,有些人给出了一些方法,比如可以通过将文件拖拽到一个<input type=”file” multiple />,并且将这个input的透明度设为0,Chrome支持将文件拖拽到input里面,所以可以触发这个input的change事件,将它提交到一个iframe里面,QQ邮箱在Chrome下貌似是采用这种方式。在这个帖子的最后面有个人给出了一个DEMO,我认为是一个比较好的解决方案,因为Chrome支持FormData,FormData为XMLHttpRequest 2提供了便捷的方法来构造表单的键值对,只需要通过send方法就可以了。最后我的关键代码是这样的:
this.uploadDragFile = function(file, index){
var xhr = new XMLHttpRequest(), _this = this;
xhr.upload.addEventListener(”progress”, function(e){
if(e.lengthComputable){
var percentage = Math.round(e.loaded*100/e.total);
$(”att_prog_drag_”+index).style.width = percentage + “%”;
}
}, false);
xhr.addEventListener(”error”, function(e){
var pn = $(”att_prog_drag_”+index).parentNode;
pn.style.display = “none”;
var em = document.createElement(”em”);
em.style.color = “red”;
em.style.marginLeft = “6px”;
em.innerHTML = “上传失败”;
pn.parentNode.insertBefore(em, pn);
}, false);
xhr.addEventListener(”load”, function(e){
var pn = $(”att_prog_drag_”+index).parentNode;
pn.style.display = “none”;
try{
eval(”var data=”+xhr.responseText+”;”);
}catch(e){
var data = null;
}
var pn = $(”att_prog_drag_”+index).parentNode;
pn.style.display = “none”;
if(data && data.result){
_this._attList["file_drag_"+index] = data["data"];
_this.setAttach(_this._attList);
}else{
var em = document.createElement(”em”);
em.style.color = “red”;
em.style.marginLeft = “6px”;
em.innerHTML = data.msg || “上传失败”;
pn.parentNode.insertBefore(em, pn);
}
}, false);
xhr.open(”POST”, “/classic/uploadatt.php?email=”+runtime._conf["uid"]);
if (typeof(window.FormData) != “undefined”) {
var form = new FormData();
form.append(”Filedata”, file);
xhr.send(form);
}else{
var boundary = “xxxxxxxx”;
xhr.setRequestHeader(”Content-Type”, “multipart/form-data; charset=x-user-defined; boundary=”+boundary);//simulate a file MIME POST request;
xhr.setRequestHeader(”Content-Length”, file.size);
var body = “–” + boundary +”\r\n”;
body += “Content-Disposition: form-data; name=’Filedata’; filename=’” + encodeURIComponent(file.name) + “‘\r\n”;
body += “Content-Type: application/octet-stream\r\n\r\n”;
body += file.getAsBinary() + “\r\n”;
body += “–” + boundary + “–”;
xhr.sendAsBinary(body);
}
};