Javascript Dropzone仅选择一个文件
我复制了一个dropzone,非常棒,但是我可以一个接一个地上传几个文件,但是我只需要上传一个文件,我不是说我只需要选择一个,但是,我只需要上传一个,我不能再上传更多的文件,直到我删除我上传的文件,并能够上传另一个,但上传文件的限制是1Javascript Dropzone仅选择一个文件,javascript,reactjs,dropzone,Javascript,Reactjs,Dropzone,我复制了一个dropzone,非常棒,但是我可以一个接一个地上传几个文件,但是我只需要上传一个文件,我不是说我只需要选择一个,但是,我只需要上传一个,我不能再上传更多的文件,直到我删除我上传的文件,并能够上传另一个,但上传文件的限制是1 import React, { useRef, useState, useEffect } from "react"; const Dropzone = () => { const fileInputRef = useRef();
import React, { useRef, useState, useEffect } from "react";
const Dropzone = () => {
const fileInputRef = useRef();
const modalImageRef = useRef();
const modalRef = useRef();
const progressRef = useRef();
const uploadRef = useRef();
const uploadModalRef = useRef();
const [selectedFiles, setSelectedFiles] = useState([]);
const [validFiles, setValidFiles] = useState([]);
const [unsupportedFiles, setUnsupportedFiles] = useState([]);
const [errorMessage, setErrorMessage] = useState("");
useEffect(() => {
let filteredArr = selectedFiles.reduce((acc, current) => {
const x = acc.find((item) => item.name === current.name);
if (!x) {
return acc.concat([current]);
} else {
return acc;
}
}, []);
setValidFiles([...filteredArr]);
}, [selectedFiles]);
const preventDefault = (e) => {
e.preventDefault();
// e.stopPropagation();
};
const dragOver = (e) => {
preventDefault(e);
};
const dragEnter = (e) => {
preventDefault(e);
};
const dragLeave = (e) => {
preventDefault(e);
};
const fileDrop = (e) => {
preventDefault(e);
const files = e.dataTransfer.files;
if (files.length) {
handleFiles(files);
}
};
const filesSelected = () => {
if (fileInputRef.current.files.length) {
handleFiles(fileInputRef.current.files);
}
};
const fileInputClicked = () => {
fileInputRef.current.click();
};
const handleFiles = (files) => {
for (let i = 0; i < files.length; i++) {
if (validateFile(files[i])) {
setSelectedFiles((prevArray) => [...prevArray, files[i]]);
} else {
files[i]["invalid"] = true;
setSelectedFiles((prevArray) => [...prevArray, files[i]]);
setErrorMessage("File type not permitted");
setUnsupportedFiles((prevArray) => [...prevArray, files[i]]);
}
}
};
const validateFile = (file) => {
const validTypes = [
"image/jpeg",
"image/jpg",
"image/png",
"image/gif",
"image/x-icon"
];
if (validTypes.indexOf(file.type) === -1) {
return false;
}
return true;
};
const fileSize = (size) => {
if (size === 0) {
return "0 Bytes";
}
const k = 1024;
const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
const i = Math.floor(Math.log(size) / Math.log(k));
return parseFloat((size / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
};
const fileType = (fileName) => {
return (
fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length) ||
fileName
);
};
const removeFile = (name) => {
const index = validFiles.findIndex((e) => e.name === name);
const index2 = selectedFiles.findIndex((e) => e.name === name);
const index3 = unsupportedFiles.findIndex((e) => e.name === name);
validFiles.splice(index, 1);
selectedFiles.splice(index2, 1);
setValidFiles([...validFiles]);
setSelectedFiles([...selectedFiles]);
if (index3 !== -1) {
unsupportedFiles.splice(index3, 1);
setUnsupportedFiles([...unsupportedFiles]);
}
};
const openImageModal = (file) => {
const reader = new FileReader();
modalRef.current.style.display = "block";
reader.readAsDataURL(file);
reader.onload = function (e) {
modalImageRef.current.style.backgroundImage = `url(${e.target.result})`;
};
};
const closeModal = () => {
modalRef.current.style.display = "none";
modalImageRef.current.style.backgroundImage = "none";
};
const closeUploadModal = () => {
uploadModalRef.current.style.display = "none";
};
return (
<>
<div className="container">
<div
className="drop-container"
onDragOver={dragOver}
onDragEnter={dragEnter}
onDragLeave={dragLeave}
onDrop={fileDrop}
onClick={fileInputClicked}
>
<div className="drop-message">
<div className="upload-icon"></div>
Drag & Drop files here or click to select file(s)
</div>
<input
ref={fileInputRef}
className="file-input"
type="file"
onChange={filesSelected}
/>
</div>
<div className="file-display-container">
{validFiles.map((data, i) => (
<div className="file-status-bar" key={i}>
<div
onClick={
!data.invalid
? () => openImageModal(data)
: () => removeFile(data.name)
}
>
<div className="file-type-logo"></div>
<div className="file-type">{fileType(data.name)}</div>
<span
className={`file-name ${data.invalid ? "file-error" : ""}`}
>
{data.name}
</span>
<span className="file-size">({fileSize(data.size)})</span>{" "}
{data.invalid && (
<span className="file-error-message">({errorMessage})</span>
)}
</div>
<div
className="file-remove"
onClick={() => removeFile(data.name)}
>
X
</div>
</div>
))}
</div>
</div>
<div className="modal" ref={modalRef}>
<div className="overlay"></div>
<span className="close" onClick={() => closeModal()}>
X
</span>
<div className="modal-image" ref={modalImageRef}></div>
</div>
<div className="upload-modal" ref={uploadModalRef}>
<div className="overlay"></div>
<div className="close" onClick={() => closeUploadModal()}>
X
</div>
<div className="progress-container">
<span ref={uploadRef}></span>
<div className="progress">
<div className="progress-bar" ref={progressRef}></div>
</div>
</div>
</div>
</>
);
};
export default Dropzone;
import React,{useRef,useState,useffect}来自“React”;
常量Dropzone=()=>{
const fileInputRef=useRef();
const modalImageRef=useRef();
const modalRef=useRef();
const progressRef=useRef();
const uploadRef=useRef();
const uploadModalRef=useRef();
const[selectedFiles,setSelectedFiles]=useState([]);
const[validFiles,setValidFiles]=useState([]);
const[unsupportedFiles,setUnsupportedFiles]=useState([]);
常量[errorMessage,setErrorMessage]=useState(“”);
useffect(()=>{
让Filteredar=selectedFiles.reduce((acc,current)=>{
const x=acc.find((项)=>item.name==current.name);
如果(!x){
返回acc.concat([当前]);
}否则{
返回acc;
}
}, []);
SetValidFile([…filteredArr]);
},[selectedFiles]);
const preventDefault=(e)=>{
e、 预防默认值();
//e.停止传播();
};
常数dragOver=(e)=>{
防止违约(e);
};
常数dragEnter=(e)=>{
防止违约(e);
};
常数dragLeave=(e)=>{
防止违约(e);
};
constfiledrop=(e)=>{
防止违约(e);
const files=e.dataTransfer.files;
if(files.length){
手文件(档案);
}
};
constfileselected=()=>{
if(fileInputRef.current.files.length){
handleFiles(fileInputRef.current.files);
}
};
const fileInputClicked=()=>{
fileInputRef.current.click();
};
常量句柄文件=(文件)=>{
for(设i=0;i[…prevArray,files[i]]);
}否则{
文件[i][“无效”]=true;
setSelectedFiles((prevArray)=>[…prevArray,files[i]]);
setErrorMessage(“不允许文件类型”);
setUnsupportedFiles((prevArray)=>[…prevArray,files[i]]);
}
}
};
const validateFile=(文件)=>{
常量有效类型=[
“图像/jpeg”,
“图片/jpg”,
“图像/png”,
“图像/gif”,
“图像/x图标”
];
if(validTypes.indexOf(file.type)=-1){
返回false;
}
返回true;
};
常量文件大小=(大小)=>{
如果(大小==0){
返回“0字节”;
}
常数k=1024;
常量大小=[“字节”、“KB”、“MB”、“GB”、“TB”];
常数i=Math.floor(Math.log(size)/Math.log(k));
返回parseFloat((size/Math.pow(k,i)).toFixed(2))+“”+size[i];
};
常量文件类型=(文件名)=>{
返回(
fileName.substring(fileName.lastIndexOf(“.”+1,fileName.length)||
文件名
);
};
const removeFile=(名称)=>{
const index=validFiles.findIndex((e)=>e.name==name);
const index2=selectedFiles.findIndex((e)=>e.name==name);
const index3=unsupportedFiles.findIndex((e)=>e.name==name);
有效文件拼接(索引1);
selectedFiles.splice(index2,1);
setValidFiles([…validFiles]);
设置所选文件([…所选文件]);
如果(index3!=-1){
无支持文件。拼接(index3,1);
setUnsupportedFiles([…unsupportedFiles]);
}
};
常量openImageModal=(文件)=>{
const reader=new FileReader();
modalRef.current.style.display=“block”;
reader.readAsDataURL(文件);
reader.onload=函数(e){
modalImageRef.current.style.backgroundImage=`url(${e.target.result})`;
};
};
const closeModal=()=>{
modalRef.current.style.display=“无”;
modalImageRef.current.style.backgroundImage=“无”;
};
const closeUploadModal=()=>{
uploadModalRef.current.style.display=“无”;
};
返回(
将文件拖放到此处或单击以选择文件
{validFiles.map((数据,i)=>(
openImageModal(数据)
:()=>removeFile(data.name)
}
>
{fileType(data.name)}
{data.name}
({fileSize(data.size)}){'}
{data.invalid&&(
({errorMessage})
)}
removeFile(data.name)}
>
X
))}
closeModal()}>
X
closeUploadModal()}>
X
);
};
导出默认Dropzone;
你可以尝试在这个链接,你会看到,你可以上传几个文件一个接一个,但我只需要上传一个,我不能再上传更多