下图是使用 iReader 阅读器 wifi 传书的一个截图,我们可以点击蓝色的选择文件按钮来选择文件,也可以直接把文件拖到这个界面。就我个人而言,更喜欢把文件拖过来上传的方式。如果有个网页有选择文件的功能,但是不支持拖拽上传,总让我觉得它很原始。
这个功能非常常用,那它是怎么做的呢?今天我们就写一个小的 Demo 来演示一下!
能实现这个功能主要是靠浏览器的 Drap API。很多同学可能不知道,当我们把电脑的文件拖动并放置目标,这样也会触发 drag 事件。
上代码!
let dropTarget = document.getElementById('app');
function handleEvent(event) {
event.preventDefault()
if (event.type === 'drop') {
const files = event.dataTransfer.files;
const reader = new FileReader();
reader.readAsDataURL(files[0]);
reader.onload = () => {
dropTarget.style.backgroundImage = reader.result;
dropTarget.style.backgroundImage = `url(${reader.result})`
}
}
}
dropTarget.addEventListener("drop", handleEvent);
dropTarget.addEventListener("dragenter", handleEvent);
dropTarget.addEventListener("dragover", handleEvent);
在代码的结尾,为什么我们要绑定三个事件呢?是为了取消 drag 过程的默认事件。
我们真正需要的只有 'drop' 这一个动作,所以我们做了 if 判断。
FileReader 对象读文件是异步的,虽然结果在 FileReader 对象的 result 属性里,但真正的结果要在 onload 事件触发后才拿的到。初始化,FileReader 对象的 onload 属性是 null,需要我们自己初始化这个函数。
最后就是 readAsDataURL 这个 API 了。它将内容数据的 URL 保存在了 FileReader 的 result 属性里。
其实有时候我们不需要将内容读过来,比如上面的那个需求,我们只需要拿到它的一个 URL ,让我们能在标签里显示就可以了。这种情况下,我们并不需要使用 FileReader ,有更简单的方法:window.URL.createObjectURL,它返回的是一个指向内存中地址的字符串。
import "./styles.css";
let dropTarget = document.getElementById('app');
function handleEvent(event) {
event.preventDefault()
if (event.type === 'drop') {
// 下面三行有变化
const files = event.dataTransfer.files;
const url = window.URL.createObjectURL(files[0]);
dropTarget.style.backgroundImage = `url(${url})`
}
}
dropTarget.addEventListener("drop", handleEvent);
dropTarget.addEventListener("dragenter", handleEvent);
dropTarget.addEventListener("dragover", handleEvent);
今天就分享这一个小技巧,收。