Javascript 不使用AJAX,在前台同步拖放文件上传?

Javascript 不使用AJAX,在前台同步拖放文件上传?,javascript,html,file-upload,Javascript,Html,File Upload,我有一个网站,定期上传文件,在提交表单时将数据发布到后端 我希望逐步增强表单,以便您可以从浏览器外部将文件放到视口中的任何位置(而不仅仅是在某些浏览器内置的文件输入字段上)以上载它 表单是否自动提交并不重要。因此,如果拖放只选择文件字段中的文件,而不启动上载,那就好了。我不需要支持多个文件。我不需要显示上传进度、缩略图或任何花哨的东西 我知道有支持拖放上传的JS库,但它们似乎都是通过AJAX上传的。我可以这样做,但是我需要修改后端和前端来处理上传错误,重定向并在成功时显示正确的消息等等 我想要一

我有一个网站,定期上传
文件,在提交表单时将数据发布到后端

我希望逐步增强表单,以便您可以从浏览器外部将文件放到视口中的任何位置(而不仅仅是在某些浏览器内置的文件输入字段上)以上载它

表单是否自动提交并不重要。因此,如果拖放只选择文件字段中的文件,而不启动上载,那就好了。我不需要支持多个文件。我不需要显示上传进度、缩略图或任何花哨的东西

我知道有支持拖放上传的JS库,但它们似乎都是通过AJAX上传的。我可以这样做,但是我需要修改后端和前端来处理上传错误,重定向并在成功时显示正确的消息等等

我想要一个渐进的增强,不需要任何后端更改。它应该使用页面中的表单同步发生。只要上传发生在“前台”,JS就可以了。当然,同步AJAX不会工作。

虽然不是真正的“同步”(JavaScript执行不会真正停止),但您可以通过编程方式设置
选择的文件。事实上,这样的元素和拖动共享它们的文件后端实现(
file
FileList
实例),所以它非常简单。更重要的是,由于两个前端都使用
FileList
s,因此拖动多个文件同样可以无缝地工作

这适用于Chrome(使用jQuery):


可以通过将autoUpload设置为false,收集数组中的文件,然后在表单提交时对所有文件和表单数据进行一次ajax调用,如前所述。

感谢@pimvdb comment,我想出了一个非常优雅的解决方案

既然在
上拖放可以工作,为什么不在
dragstart
上全屏显示以确保用户不会错过它?无论如何,他是拖拉,所以他的意图在这一刻是明确的

下面是一个演示:

注:不幸的是,这在
iframe
中似乎不起作用,但在实际页面上确实起作用。你仍然可以理解这种行为

以下是片段:

$('input[type=“file”]”)。在('change',函数(e)上{
var fileName=e.target.files[0]。名称;
如果(文件名){
$(e.target).parent().attr('data-message',文件名);
}
});
$(文档).on('drag dragstart dragend dragover dragenter dragleave drop',函数(e){
if($('input[type=“file”]”).length){
if(['dragover','dragenter'].indexOf(e.type)>-1){
if(窗口dragTimeout)
clearTimeout(window.dragTimeout);
$('body').addClass('dradded');
}else if(['dragleave','drop'].indexOf(e.type)>-1){
//如果没有超时,则会触发一些dragleave事件
//当:after出现时,使其闪烁。。。
window.dragTimeout=setTimeout(函数(){
$('body').removeClass('Drawed');
}, 100);
}
}
});
h3,p{
文本对齐:居中;
}
.表格组{
利润率:30像素;
}
.file upload.form控件{
高度:150像素;
轮廓:1px虚线#ccc;
轮廓偏移:-15px;
背景色:#eee;
}
.file upload.form控件:之前{
内容:“\f093”;
字体:普通14px/1字体;
字号:3em;
左:0;
右:0;
显示:块;
保证金:20px自动;
文本对齐:居中;
}
.file upload.form控件:之后{
内容:attr(数据报文);
左:0;
右:0;
底部:0;
文本对齐:居中;
显示:块;
}
.file upload.form控件输入[type=“file”]{
光标:指针;
不透明度:0;
宽度:100%;
身高:100%;
位置:绝对位置;
排名:0;
底部:0;
右:0;
左:0;
}
body.dradded.file upload.form控件输入[type=“file”]{
/*确保它是全屏的,无论绝对容器的位置如何*/
位置:固定;
顶部:-50vh;
底部:-50vh;
左:-50vw;
右图:-50vw;
高度:200vh;
宽度:200vw;
z指数:10002;
}
正文:之后{
内容:“您可以删除文件。:-”;
字号:2em;
文本对齐:居中;
线路高度:100vh;
位置:绝对位置;
顶部:10px;
底部:10px;
左:10px;
右:10px;
背景色:#eee;
z指数:10000;
边界半径:4px;
边框:薄实线#ccc;
可见性:隐藏;
不透明度:0;
过渡:可见性为0,不透明度为0.5;
}
身体。拖:之后{
不透明度:1;
能见度:可见;
}

拖放文件上载,无需AJAX演示
尝试拖放文件。:-)

文件上传

在Chrome中,您至少可以在drop上设置文件输入的文件:。这就是你想要的吗?@pimvdb真漂亮!正是我想要的。我忘了提到,因为这是一个内部服务,铬只是罚款。如果你把它作为一个答案(除了评论之外),我会把它标记为接受。@Henrik N:我现在意识到它不喜欢Windows上的
.lnk
文件。通过输入元素选择它们将选择快捷方式链接到的文件,而删除
.lnk
文件将获得
.lnk
文件本身。这对于我的用例来说不是问题。再次感谢你!有没有关于跨浏览器解决方案的想法?(刚刚在FF16:not working上测试了prop())@Bogdan D:看起来Firefox在将文件放到
输入[type='file']
元素时默认接受这种行为(即,不要插入上面的JavaScript代码)。不知道如何从整个文档中传递这种行为。@pimvdb感谢您的回答(投票结果),这种行为对我来说已经足够好了!现在进入IE10的奇特世界(当然以上没有一项工作),我将发布任何有用的发现……谢谢,但请注意“没有”
$(document).on("dragover drop", function(e) {
    e.preventDefault();  // allow dropping and don't navigate to file on drop
}).on("drop", function(e) {
    $("input[type='file']")
        .prop("files", e.originalEvent.dataTransfer.files)  // put files into element
        .closest("form")
          .submit();  // autosubmit as well
});