一、基本介紹
input type file 是HTML表單元素中用於上傳文件的標籤。它允許用戶從本地設備中選擇一個或多個文件作為它們想要上傳的內容。
這個標籤的type屬性值為file,它由一個文件選擇框和一個上傳按鈕組成,通過點擊上傳按鈕或者按下回車鍵就可以上傳文件了。
下面的代碼段是最基本的input type file的用法:
<form>
<p>請選擇文件</p>
<input type="file">
<input type="submit">
</form>
二、accept屬性
accept屬性規定了上傳文件時對文件的類型進行限定。如果使用accept屬性,那麼在文件選擇器中,用戶只能看到符合要求的文件類型。
accept屬性有兩種限制方式,一種是通過文件擴展名限制,一種是通過MIME類型限制。下面是一個MIME類型限制的示例代碼:
<input type="file" accept="image/*">
上述代碼中 accept 屬性的值為「image/*」,表示限制上傳的文件類型必須是圖像文件。通配符*表示匹配任何文件類型的圖像,包括jpg、png、gif等。
三、multiple屬性
multiple屬性用於指定是否允許選擇多個文件進行上傳。該屬性值為布爾類型。
如果使用multiple屬性,那麼文件選擇器中會顯示一個多選框,用戶可以通過該多選框選擇多個文件,從而將這些文件一次性上傳。
下面是一個multiple屬性的示例:
<input type="file" multiple>
四、files屬性
當用戶通過input type file選擇了文件後,瀏覽器會將文件作為File對象存儲在files屬性中。
我們可以使用JavaScript對文件進行處理,比如可以讀取文件的二進制數據、上傳文件等等。以下是一個簡單的示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>讀取文件數據</title>
</head>
<body>
<input type="file" id="fileInput">
<script>
const fileInput = document.getElementById('fileInput');
fileInput.addEventListener('change', (event) => {
const file = event.target.files[0];
const reader = new FileReader();
reader.readAsText(file);
reader.onload = () => {
console.log(reader.result);
};
});
</script>
</body>
</html>
上面的代碼演示了如何在文件選擇器選擇文件,然後將文件的文本數據通過console.log()輸出到瀏覽器控制台。
五、拓展
當然,以上只是input type file的基本使用方法,實際上,該標籤還有很多值得探討的方面,比如上傳進度條的實現、多個input type file的處理、授權等等。
下面是一個完整的input type file示例,涵蓋了基本的上傳功能,上傳進度條,文件列表展示等等。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>文件上傳</title>
<style>
.progress {
position: relative;
width: 100%;
height: 4px;
background-color: #f5f5f5;
border-radius: 2px;
margin-top: 10px;
}
.progress .bar {
position: absolute;
left: 0;
top: 0;
height: 100%;
background-color: #2d8cf0;
border-radius: 2px;
transition: width 0.3s linear;
}
.file-item {
padding: 10px;
border-bottom: 1px solid #eee;
display: flex;
align-items: center;
}
.file-item .file-info {
flex: 1;
margin-left: 10px;
}
.file-item .file-name {
font-size: 16px;
font-weight: bold;
}
.file-item .file-size {
font-size: 12px;
color: #ccc;
margin-top: 5px;
}
.file-item .file-progress {
display: flex;
margin-top: 5px;
align-items: center;
}
.file-item .file-progress .progress {
width: 100px;
height: 4px;
margin-left: 10px;
margin-right: 10px;
}
.file-item .file-progress .progress .bar {
background-color: #f0ad4e;
}
</style>
</head>
<body>
<form id="upload-form">
<input type="file" name="file" id="file" multiple>
<input type="button" value="選擇文件">
<input type="submit" value="上傳">
</form>
<div id="file-list"></div>
<script>
const fileList = [];
const form = document.getElementById('upload-form');
const fileInput = document.getElementById('file');
const fileListElm = document.getElementById('file-list');
const btn = document.querySelector('input[type="button"]');
const progressBar = document.createElement('div');
const createFileItem = (file) => {
const fileItem = document.createElement('div');
const fileInfo = document.createElement('div');
const fileName = document.createElement('div');
const fileSize = document.createElement('div');
const fileProgress = document.createElement('div');
const progress = document.createElement('div');
const bar = document.createElement('div');
fileItem.className = 'file-item';
if (file.type.startsWith('image/')) {
const img = document.createElement('img');
img.src = URL.createObjectURL(file);
img.width = 100;
img.height = 100;
fileItem.appendChild(img);
} else {
const icon = document.createElement('i');
icon.className = 'fa fa-file-o';
fileItem.appendChild(icon);
}
fileInfo.className = 'file-info';
fileName.className = 'file-name';
fileSize.className = 'file-size';
fileProgress.className = 'file-progress';
progress.className = 'progress';
bar.className = 'bar';
fileName.innerText = file.name;
fileSize.innerText = formatFileSize(file.size);
fileItem.appendChild(fileInfo);
fileInfo.appendChild(fileName);
fileInfo.appendChild(fileSize);
fileItem.appendChild(fileProgress);
fileProgress.appendChild(progress);
progress.appendChild(bar);
fileListElm.appendChild(fileItem);
return fileItem;
};
const handleFileSelect = (event) => {
event.stopPropagation();
event.preventDefault();
const files = event.dataTransfer ? event.dataTransfer.files : event.target.files;
for (const file of files) {
const fileItem = createFileItem(file);
fileList.push({
file,
fileItem,
progressbar: new ProgressBar(fileItem.querySelector('.progress'), 0)
});
}
form.classList.add('uploading');
};
const handleDragOver = (event) => {
event.stopPropagation();
event.preventDefault();
event.dataTransfer.dropEffect = 'copy';
};
const uploadFile = (file, onProgress) => {
const formData = new FormData();
formData.append('file', file);
const xhr = new XMLHttpRequest();
xhr.open('POST', '/upload');
xhr.upload.addEventListener('progress', ({loaded, total}) => {
onProgress(loaded / total);
});
xhr.send(formData);
};
btn.addEventListener('click', () => {
fileInput.click();
});
fileInput.addEventListener('change', handleFileSelect);
form.addEventListener('dragover', handleDragOver);
form.addEventListener('drop', handleFileSelect);
form.addEventListener('submit', (event) => {
event.preventDefault();
for (const {file, fileItem, progressbar} of fileList) {
progressbar.show();
uploadFile(file, (progress) => {
progressbar.update(progress);
}).then(() => {
progressbar.close();
fileItem.querySelector('.file-name').style.textDecoration = 'line-through';
});
}
fileList.length = 0;
form.classList.remove('uploading');
});
class ProgressBar {
constructor(elm, progress) {
this.elm = elm;
this.bar = elm.querySelector('.bar');
this.progress = progress;
this.update(progress);
}
update(progress) {
this.progress = progress;
this.bar.style.width = Math.round(this.progress * 100) + '%';
}
show() {
this.elm.style.display = 'block';
}
close() {
this.elm.style.display = 'none';
}
}
function formatFileSize(size) {
const units = ['B', 'KB', 'MB', 'GB'];
let index = 0;
while(size >= 1024 && index < units.length - 1) {
size /= 1024;
index++;
}
return size.toFixed(2) + units[index];
}
</script>
</body>
</html>
上述示例代碼實現了基本的文件上傳功能,包括單個文件上傳和多個文件上傳,上傳進度條的展示,文件列表的展示等等。具體的細節解釋可在代碼中查看。
原創文章,作者:BATSJ,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/334222.html
微信掃一掃
支付寶掃一掃