Skip to content

轻松上传文件:通过拖拽和复制实现

831字约3分钟

HTMLJavaScript

2024-07-25

通常我们上传文件是通过 <input type=file /> 标签实现的,但是它是不支持拖拽和复制的。下面介绍两种额外的获取文件方法:

  • 拖拽上传:直接拖拽设备文件放到指定元素上,获取文件。主要事件:drop
  • 复制上传:通过 Ctrl + VCtrl + V 复制文件到指定元素上,获取文件。主要事件:paste

input 上传

先来看一下最基本的input上传,我们通过监听change事件,获取文件对象,然后通过FileReader读取文件内容。

示例代码:

<input name="图片上传" type="file" accept="image/*" id="uploadImage"/>
const input = document.getElementById('uploadImage');
input.addEventListener('change', (event) => {
    const files = event.target.files;
    if (files.length > 0) {
        console.log('处理file')
    }
})

具体演示:

input file 上传演示
 <input name="图片上传" type="file" accept="image/*" id="uploadImage"/>
 <br/>
 <img id="img"/>
const convertToBase64 = (file) => {
    const reader = new FileReader();
    reader.onload = (event) => {
        const base64String = event.target.result;
        const img = document.getElementById('img');
        // 预览
        img.src = base64String;
    };
    reader.readAsDataURL(file);
};
const isImageFile = (file) => {
    return file.type.startsWith("image/");
};
const input = document.getElementById('uploadImage');
input.addEventListener('change', (event) => {
    const files = event.target.files;
    if (files.length > 0) {
        const file = files[0];
        const maxSize = 2 * 1024 * 1024;
        if (file.size > maxSize) {
            alert('图片大小超过限制,请重新选择!');
            return;
        }
        if (isImageFile(file)) {
            convertToBase64(file);
        } else {
            alert('请选择图片文件!');
        }
    }
})
img  {
    margin: 20px 0;
    border-radius: 12px;
    width: 200px;
    height: 200px;
    background-color: #ccc;
 }

拖拽上传

拖拽上传是通过监听drop事件,获取拖拽的文件对象,然后通过FileReader读取文件内容。

示例代码:

 <div id="dropUploadImage"> 将文件拖拽到此处 </div>
const dropElement = document.getElementById('dropUploadImage');
// 阻止默认行为
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
    dropElement.addEventListener(eventName, preventDefaults, false);
});
function preventDefaults(e) {
    e.preventDefault();
    e.stopPropagation();
}
dropElement.addEventListener('drop', (e) => {
    e.preventDefault();
    const files = e.dataTransfer.files;
    if (files && files.length > 0) {
        console.log('处理file')
    }
})

具体演示:

拖拽图片上传演示
 <div id="dropUploadImage"> 将文件拖拽到此处 </div>
 <img id="dropImg"/>
const convertToBase64 = (file) => {
    const reader = new FileReader();
    reader.onload = (event) => {
        const base64String = event.target.result;
        const img = document.getElementById('dropImg');
        // 预览
        img.src = base64String;
    };
    reader.readAsDataURL(file);
};
const isImageFile = (file) => {
    return file.type.startsWith("image/");
};
const dropElement = document.getElementById('dropUploadImage');
// 阻止默认行为
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
    dropElement.addEventListener(eventName, preventDefaults, false);
});
function preventDefaults(e) {
    e.preventDefault();
    e.stopPropagation();
}
dropElement.addEventListener('drop', (e) => {
    e.preventDefault();
    const files = e.dataTransfer.files;
    if (files && files.length > 0) {
        const file = files[0]
        if (file) {
            const maxSize = 2 * 1024 * 1024;
            if (file.size > maxSize) {
                alert('图片大小超过限制,请重新选择!');
                return;
            }
            if (isImageFile(file)) {
                convertToBase64(file);
            } else {
                alert('请选择图片文件!');
            }
        }
    }
})
#dropUploadImage {
    display: inline-block;
    width: 200px;
    height: 200px;
    border: 1px dashed #ccc;
    text-align: center;
    line-height: 200px;
    font-size: 24px;
    color: #ccc;
    box-sizing: border-box;
}
img  {
    vertical-align: bottom;
    margin: 0 20px;
    border-radius: 12px;
    width: 200px;
    height: 200px;
    background-color: #ccc;
 }

粘贴上传

粘贴上传是通过监听paste事件,获取剪贴板的文件对象,然后通过FileReader读取文件内容。

示例代码:

 <input id="pasteUploadImage" type="text" />
const pasteUploadImage = document.getElementById('pasteUploadImage');
pasteUploadImage.addEventListener('paste', (event) => {
    const items = event.clipboardData!.items;
    for (let item of items) {
        if (item.kind === "file" && item.type.startsWith("image/")) {
            // 图片的话阻止默认
            event.preventDefault();
            const blob = item.getAsFile();
            console.log('处理file')
        }
    }
})

具体演示:

复制图片粘贴上传演示
 <input id="pasteUploadImage" type="text" />
 <img id="pasteImg"/>
const pasteUploadImage = document.getElementById('pasteUploadImage');
const pasteImg = document.getElementById('pasteImg');
pasteUploadImage.addEventListener('paste', (event) => {
    const items = event.clipboardData.items;
    for (let item of items) {
        if (item.kind === "file" && item.type.startsWith("image/")) {
            // 图片的话阻止默认
            event.preventDefault();
            const blob = item.getAsFile();
            const reader = new FileReader();
            reader.onload = function (e) {
                pasteImg.src = e.target.result;
            };
            reader.readAsDataURL(blob);
        }
    }
})
#pasteUploadImage {
    outline: none;
    border: 1px solid #ccc;
    display: block;
    width: 280px;
    height: 32px;
    line-height: 48px;
    font-size: 16px;
    color: #666;
    padding: 0 12px;
    border-radius: 12px;
}
img  {
    vertical-align: bottom;
    margin:  20px 0;
    border-radius: 12px;
    width: 200px;
    height: 200px;
    background-color: #ccc;
 }