如何实现文件拖拽上传功能?拖拽上传句柄包含什么信息?
发布于 作者:苏南大叔 来源:程序如此灵动~ 我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...
苏南大叔说一个几年前很酷的功能的实现方式,就是拖拽上传功能。在网页上有个区域,拖拽文件进入后,并不是默认的打开文件,而是实现了文件的上传功能。
苏南大叔的程序如此灵动博客,记录苏南大叔和计算机代码的故事。测试环境:谷歌浏览器@108.0.5359.125。
前置文章
这里有几篇前置文章,可以帮助本文的理解。
本文的内容和下面这篇文章,其实很相似。下面的文章是利用常见的上传组件上传,本文中并没有上传组件,读取的是拖拽文件的句柄。参考文字:
屏蔽js事件
首先,屏蔽了上传容器的几个拖拽事件,使用的方式是:e.preventDefault();
。代码如下:
<div class="box">拖拽文件到这个位置</div>
<script>
let drop_box = document.querySelector(".box");
drop_box.addEventListener("dragenter", function () {
console.log("进入"); // 只进入一次
});
drop_box.addEventListener("dragover", function (e) {
e.preventDefault();
console.log("over"); // 连续over
});
</script>
关于阻止事件冒泡的方法:
拿到拖拽文件句柄
drop_box.addEventListener(
"drop",
function (e) {
e.preventDefault();
var _files = e.dataTransfer.files; // 这个就相当于文件上传组件
// doUpload(_files);
},
false
);
这里利用容器的drop
事件,监控了e.dataTransfer.files
,这个就相当于文件上传组件的.files
。对比如下:
方式 | 代码 |
---|---|
拖拽上传 | e.dataTransfer.files |
组件点击上传 | document.getElementById("file_input").files |
关于事件参数的传递:
构建FormData
拿到files
对象后,就是构建上传表单对象FormData
了。然后就是常规的ajax
上传,这里依然使用了jquery
来实现这个需求。
function doUpload(_files) {
for (let i = 0; i < _files.length; i++) {
var data2 = new FormData();
data2.append("file", _files[i]);
$.ajax({
async: true,
url: "upload.php",
type: "POST",
cache: false,
processData: false,
contentType: false,
data: data2,
timeout: 60000,
success: function (json) {
console.log(json);
},
error: function (json) { },
});
}
}
完整代码
<script src="https://cdn.bootcss.com/jquery/3.1.0/jquery.min.js"></script>
<style>
.box {
width: 300px;
height: 80px;
border: 1px solid #ccc;
line-height: 80px;
text-align: center;
color: #ccc;
}
</style>
<div class="box">拖拽文件到这个位置</div>
<script>
let drop_box = document.querySelector(".box");
drop_box.addEventListener("dragstart", function (e) {
e.preventDefault();
console.log("进入"); // 只进入一次
});
drop_box.addEventListener("dragenter", function (e) {
e.preventDefault();
console.log("进入"); // 只进入一次
});
drop_box.addEventListener("dragover", function (e) {
e.preventDefault();
console.log("over"); // 连续over
});
drop_box.addEventListener(
"drop",
function (e) {
e.stopPropagation(); // firefox必须加上这句话
e.preventDefault();
var _files = e.dataTransfer.files; // 这个就相当于文件上传组件
doUpload(_files);
},
false
);
function doUpload(_files) {
for (let i = 0; i < _files.length; i++) {
var data2 = new FormData();
data2.append("file", _files[i]);
$.ajax({
async: true,
url: "upload.php",
type: "POST",
cache: false,
processData: false,
contentType: false,
data: data2,
timeout: 60000,
success: function (json) {
console.log(json);
},
error: function (json) { },
});
}
}
</script>
这里并不描述后端的实现代码,根据不同的后端语言,实现的方式很多。接收file
参数代表的文件即可。
可以参考:
firefox
特殊处理
关于阻止事件冒泡的语句:
e.stopPropagation(); // firefox必须加上这句话
e.preventDefault();
在firefox
浏览器中测试的时候,也会正常上传,同时还会自动打开文件(浏览器默认行为)。所以加上了.stopPropagation()
阻止事件冒泡。
事件冒泡的文章,请点击:
拖拽句柄里面包含的信息
e.dataTransfer.files
里面,包含文件的基本信息。包括:
属性 | 值 |
---|---|
lastModified | 1671180126355 |
lastModifiedDate | Fri Dec 16 2022 16:42:06 GMT+0800 (中国标准时间) {} |
name | empty.png |
size | 1163 |
type | image/png |
webkitRelativePath | "" |
还可以使用FileReader
来读取更详细的信息(比如文件的内容)。参考文字:
结束语
文件拖拽上传,感觉很神秘,其实就是获得e.dataTransfer.files
对象,然后构造FormData
就可以实现上传。更多文章,请参考:
如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。