You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript多文件上传:新增文件时input丢失已选文件问题求助

解决文件输入重置丢失已选文件的问题

问题原因

浏览器出于安全限制,不允许修改文件输入框的files属性,每次选择新文件时,输入框会重置为当前选择的文件集合,导致之前的文件丢失。因此我们需要手动维护一个全局数组来存储所有已选择的文件。

修改后的完整代码

HTML(无需改动)

<input type="file" multiple id="gallery-photo-add" name="file[]" class="form-control custom-file-input btn btn-info" value="">

JavaScript

// 全局数组存储所有已选择的文件
let selectedFiles = [];

var imagesPreview = function (files) {
    if (files.length > 0) {
        // 移除默认占位图
        $('.no-image').parent().remove();

        const filesAmount = files.length;
        const totalItens = $('.carousel-inner > .item').length;
        const itensSum = filesAmount + totalItens;

        // 更新标题中的文件总数
        $('.slider-total-items > span').html(`(${itensSum})`);

        // 遍历每个新选择的文件
        for (let i = 0; i < filesAmount; i++) {
            const file = files[i];
            const reader = new FileReader();

            reader.onload = function (event) {
                $('.carousel-inner > .item').removeClass('active');
                
                let html = '';
                // 处理视频文件
                if (file.type.startsWith('video/')) {
                    html = `<div class="item ${i === 0 ? 'active' : ''}">
                                <video width="320" height="210" controls>
                                    <source src="${event.target.result}">
                                </video>
                            </div>`;
                } else {
                    // 处理图片文件,确定激活状态
                    const isActive = (totalItens === 0 && i === 0) || 
                                     (filesAmount > 1 && i === filesAmount - 1) || 
                                     (filesAmount === 1 && i === 0);
                    html = `<div class="item text-center posts-images-edit ${isActive ? 'active' : ''}">
                                <img src="${event.target.result}">
                            </div>`;
                }

                $(html).appendTo('.carousel-inner');
            };

            // 显示轮播控件(如果文件数量大于1)
            if (itensSum > 1) {
                $('#galleryControls').removeClass('hide');
            }

            reader.readAsDataURL(file);
        }
    }
};

$(function () {
    $('#gallery-photo-add').on('change', function () {
        if (!this.files.length) return;
        
        // 将新选择的文件添加到全局数组
        selectedFiles.push(...Array.from(this.files));
        // 预览新选择的文件
        imagesPreview(this.files);
        // 重置输入框,允许重复选择相同文件
        this.value = '';
    });

    // 表单提交处理(示例)
    $('#your-form-id').on('submit', function (e) {
        e.preventDefault();
        const formData = new FormData();
        
        // 将所有已选文件添加到FormData
        selectedFiles.forEach(file => {
            formData.append('file[]', file);
        });

        // 添加其他表单字段(如果需要)
        // formData.append('other-field', $('#other-field').val());

        // AJAX提交
        $.ajax({
            url: this.action,
            method: this.method,
            data: formData,
            processData: false,
            contentType: false,
            success: function (res) {
                // 处理成功逻辑
                console.log('上传成功', res);
            },
            error: function (xhr) {
                // 处理错误逻辑
                console.error('上传失败', xhr);
            }
        });
    });
});

关键改动说明

  1. 全局文件数组:新增selectedFiles数组,用于累积所有用户选择的文件。
  2. 修复FileReader异步问题:在循环内为每个文件创建独立的FileReader实例,并使用let声明循环变量,避免闭包导致的文件引用错误。
  3. 重置输入框:每次选择文件后重置输入框的值,允许用户重复选择相同的文件。
  4. 表单提交处理:通过FormData手动添加所有已选文件,确保提交时包含全部文件。

内容的提问来源于stack exchange,提问作者Filipe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 00:05:46