拖放文件上传可以在Firefox 3.6中完成。
A Google search for html5 drag-and-drop file uploading -gmail提供了类似的内容:
所有这些指南都使用FileReader
(或Firefox 3.6已弃用的getAsBinary
,这是其他任何浏览器都不支持的。)
然而,Google最近发布了Gmail更新,允许在Chromium和Firefox以及Chromium does not have FileReader
上传文件上传。我每晚都在使用最新的Chromium,它可以拖放上传文件,但不支持FileReader
。
我见过有人提到可以通过拖动到<input type="file" />
来实现拖放上传,但这样一次只能支持一个文件,而Gmail的上传程序可以处理拖动到其上的多个文件,所以这显然不是他们正在做的事情。
所以问题是,他们是如何做到的?你如何支持Chromium进行HTML5文件上传?另外,你能支持Safari吗?
答案 0 :(得分:33)
警告:这是旧版Safari和Chrome的兼容性代码。现代浏览器都支持FileReader API;这是一个教程:https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications
此代码现在仅在您出于某种原因需要支持Safari 5及更早版本或Chrome 6及更早版本时才有用。
一种可能性是使用the method used in SwellJS:
像这样使用<input type="file" multiple="multiple" />
:
<form method="post" enctype="multipart/form-data" id="uploadform">
<input type="file" name="dragupload[]" multiple="multiple"
onchange="if (this.value) document.getElementById('uploadform').submit();" />
</form>
输入元素的样式可以设置为opacity: 0
,并且(绝对)位于接受上传的元素上。整个表单可以放在iframe
内,用于“伪Ajax”之类的行为。并且上传元素可以是隐藏的图层,直到将某些内容拖过它。
这样的iframe看起来像:
<script>
<!--
var entered = 0;
-->
</script>
<body ondragenter="entered++;document.getElementById('uploadelement').style.display='block'" ondragleave="entered--;if (!entered) document.getElementById('uploadelement').style.display='none'">
<form method="post" enctype="multipart/form-data" id="uploadform">
Things can be dragged and dropped here!
<input type="file" id="uploadelement" name="dragupload[]" multiple="multiple" onchange="if (this.value) { document.getElementById('uploadform').submit(); }" style="display:none;position:absolute;top:0;left:0;right:0;bottom:0;opacity:0;" />
</form>
</body>
这应该仅在检测到Safari或Chrome时执行(因为其他浏览器不支持拖放到<input type="file" />
元素上),并且可以与HTML5 drop
结合使用Firefox 3.6 +的事件。
我无法判断这是否是Gmail使用的方法,但它肯定也有效。
答案 1 :(得分:13)
您可能对更符合技术和浏览器的内容感兴趣。
我觉得Plupload做得很好,支持以下功能:
对于以下大多数技术:
是的,since 2010.05.27,它支持在Chrome测试版上运行HTML5的拖放功能。
答案 2 :(得分:10)
经过很多很多侦探工作后,我在Chrome上工作了一些东西。此仅适用于Chrome。在Safari上,它冻结了。在Firefox上,它不会让我删除该文件。 IE会打开删除的文件。即使在Chrome中,拖放只能运行一次,出于某种原因,之后您必须刷新页面。 (可能的原因是事件处理程序出了问题。)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript">
window.onload = function () {
var div = document.getElementById('div');
div.ondragenter = div.ondragover = function (e) {
e.preventDefault();
e.dataTransfer.dropEffect = 'copy';
return false;
}
div.ondrop = function (e) {
for (var i = 0; i < e.dataTransfer.files.length; i++) { // e.dataTransfer is a DataTransfer object (https://developer.mozilla.org/En/DragDrop/DataTransfer), e.dataTransfer.files is a FileList object (https://developer.mozilla.org/en/DOM/FileList)
var file = e.dataTransfer.files[i]; // file is a File object (https://developer.mozilla.org/en/DOM/File)
var xhr = new XMLHttpRequest;
xhr.open('post', 'handler.php', true);
xhr.onreadystatechange = function () {
if (this.readyState != 4)
return;
document.body.innerHTML += '<pre>' + this.responseText + '</pre>';
}
xhr.setRequestHeader('Content-Type', 'multipart/form-data');
xhr.setRequestHeader('X-File-Name', file.fileName);
xhr.setRequestHeader('X-File-Size', file.fileSize);
xhr.send(file); // For some reason sending the actual File object in Chrome works?
}
e.preventDefault();
return false;
}
}
</script>
</head>
<body>
<div id="div" style="width: 100%; height: 200px; border: 1px solid blue">Drop here</div>
</body>
</html>
handler.php:
// This is not a true file upload. Instead, it sends the raw data directly.
echo htmlentities(file_get_contents('php://input'));
答案 3 :(得分:2)
您不需要使用iframe来执行伪ajax上传。 Chrome和Safari都支持XHR2 uploads进度事件,因此您可以执行进度条等。
答案 4 :(得分:2)
对于我们自己的应用程序,我们只对FireFox进行拖放操作。我们恢复为其他人传统的iframe上传。为了检测支持拖放,我们运行以下代码:
if (typeof(window.File) == 'object' && typeof(window.FileReader) == 'function' && typeof(window.FileList) == 'object') {
// DnD is supported!
}
希望这对某些人有帮助。
答案 5 :(得分:2)
您可以使用html5uploader库:http://code.google.com/p/html5uploader/
适用于Firefox,Safari和Chrome。
答案 6 :(得分:1)
最新的浏览器支持文件上传得很好。 你可以使用:
xhr = new XMLHttpRequest();
xhr.open('POST', targetPHP, true);
var formData = new FormData();
formData.append('upload',file);
xhr.send(formData);
你不需要设置边界或任何头部,就像这样工作正常。 我测试了这段代码 客户端:firefox 6.02和chrome 13。 server:tomcat with“spring mvc”
答案 7 :(得分:0)
您可以使用FormData存储文件,然后上传它。例如
function setUp(){
var dropContainer = document.getElementById("container");
dropContainer.addEventListener("drop",dropHandler,false);
dropContainer.addEventListener("dragenter", function(event){event.stopPropagation();event.preventDefault();}, false);
dropContainer.addEventListener("dragover", function(event){event.stopPropagation();event.preventDefault();}, false);
dropContainer.addEventListener("drop", dropHandler, false);
getResult()
}
function dropHandler(event){
var files = event.dataTransfer.files;
var count = files.length;
form = new FormData();
for(var i= 0;i<count;i++){
form.append("file"+i, files[i]);
}
sendData();
}
function sendData(){
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", uploadProgress, false);
xhr.addEventListener("load", uploadComplete, false);
xhr.addEventListener("error", uploadFailed, false);
xhr.open("POST", "/upload");
xhr.send(form);
var progressBar = document.getElementById('progressBar');
progressBar.style.display = 'block';
progressBar.style.width = '0px';
}
演示在这里(http://flexinnerp.appspot.com/) 只是享受它:))
答案 8 :(得分:0)
设置多个属性,如:
input type =“file”name =“file1”multiple =“multiple”class =“DropHere”
并使用此CSS DropHere类:
.DropHere
{
height: 100px;
padding: 3px;
border: 2px dashed #555;
border-radius: 5px;
cursor: default;
background-image:url("data:image/svg+xml;utf8, <svg xmlns='http://www.w3.org/2000/svg' version='1.1' height='100px' width='220px'><text x='55' y='75' font-size='20'>or drop files here</text></svg>");
background-repeat: no-repeat;
}
现在,文件字段如下所示:
如果您使用asp.net,您可能也喜欢这篇文章我写的“使用进度条和拖放进行多个文件上传”:http://www.codeproject.com/Articles/818561/Multiple-file-upload-with-progress-bar-and-drag-an