返回
如何解决单次添加多个文件时文件数组被覆盖的问题?
javascript
2024-03-22 00:28:15
解决单次添加多个文件时上传字段覆盖文件数组的问题
问题
当你在表单中具有文件上传字段时,你希望在一次选择多个文件时,它们都能正确显示在数组中。然而,当逐个添加文件时,你可能会遇到一个问题:只有数组中添加的最后一个文件可见,表明数组被覆盖或重新定义了。
根源
这个问题的根源在于未正确更新数组并防止覆盖。当逐个添加文件时,需要确保将文件推送到数组并创建相应的视觉元素,同时防止数组被覆盖。
解决方案
为了解决这个覆盖问题,我们需要遵循一些步骤:
- 创建初始空数组: 在定义文件数组时,将其初始化为空数组,例如:
const filesArray = []
。 - 遍历文件: 当用户选择文件时,遍历
files
对象,该对象包含所选文件的信息。 - 检查文件: 对每个文件进行验证,确保其满足大小和格式限制。如果不满足限制,显示错误消息并停止添加文件。
- 将文件推送到数组: 如果文件满足限制,将其推送到
filesArray
中,例如:filesArray.push(file)
。 - 创建文件项: 为每个添加的文件创建一个视觉元素(例如,一个
div
元素),显示文件名和一个删除按钮。 - 将文件项添加到列表: 将创建的文件项添加到文件列表中,例如:
fileListDiv.appendChild(fileItem)
。 - 添加删除事件监听器: 为每个删除按钮添加一个事件监听器,以便在点击时从
filesArray
中删除相应的文件并从文件列表中删除文件项。
通过遵循这些步骤,你可以确保在单次添加多个文件时正确更新数组,而不会出现覆盖问题。
示例代码
以下示例代码演示了解决此问题的实际方法:
const uploadField = document.getElementById('00N1Q00000Tnupu') as HTMLInputElement; //id do campo de upload
const fileListDiv = document.getElementById('fileList') as HTMLDivElement;
const filesArray: File[] = []; //初始化空数组
uploadField?.addEventListener('change', function () {
const files = uploadField.files;
if (files) {
for (let i = 0; i < files.length; i++) {
const file = files[i];
const fileName = file.name;
const fileSizeMB = file.size / (1024 * 1024);
const allowedFormats = ['jpg', 'png', 'pdf', 'docx', 'xlsx', 'zip'];
const fileExtension = fileName.split('.').pop()?.toLowerCase();
if (fileSizeMB > 10 || !allowedFormats.includes(fileExtension || '')) {
const erroDiv = document.querySelector('.feedback[data-input="00N1Q00000Tnupu"]');
erroDiv.classList.remove('hidden');
erroDiv.classList.add('error');
const erroDivSpan = document.querySelector('.feedback[data-input="00N1Q00000Tnupu"] span');
// eslint-disable-next-line max-len
erroDivSpan.innerHTML = 'Please check the uploaded file(s). Make sure that all files are in the allowed formats (jpg, png, pdf, docx, xlsx, zip) and the total size of the files does not exceed 10MB.';
return;
}
filesArray.push(file); //将文件推送到数组
const fileItem = document.createElement('div');
fileItem.textContent = fileName;
const removeButton = document.createElement('i');
removeButton.classList.add('icon-trash');
removeButton.style.color = '#a71900';
removeButton.style.marginLeft = '5px';
removeButton.style.cursor = 'pointer';
removeButton.addEventListener('click', () => {
const index = filesArray.indexOf(file);
if (index !== -1) {
filesArray.splice(index, 1);
}
fileListDiv.removeChild(fileItem);
});
fileItem.appendChild(removeButton);
fileListDiv.appendChild(fileItem);
}
}
const erroDiv = document.querySelector('.feedback[data-input="00N1Q00000Tnupu"]');
erroDiv.classList.add('hidden');
erroDiv.classList.remove('error');
});
常见问题解答
- 为什么文件数组会被覆盖?
原因可能是未正确地将文件推送到数组,或者在逐个添加文件时覆盖了数组。 - 如何防止数组被覆盖?
通过初始化一个空数组并使用push()
方法来添加文件,而不是重新分配数组,可以防止覆盖。 - 是否可以一次添加多个文件?
是的,通过使用multiple
属性,你可以一次选择多个文件。 - 如何显示已添加文件的视觉表示?
对于每个添加的文件,创建一个视觉元素,例如一个div
元素,其中包含文件名和一个删除按钮。 - 如何从数组中删除文件?
为每个删除按钮添加一个事件监听器,以便在点击时从数组中删除文件并从文件中删除视觉表示列表。