首页 > web前端 > js教程 > 正文

使用 jQuery 实现多文件上传预览与删除功能

碧海醫心
发布: 2025-11-22 15:28:14
原创
773人浏览过

使用 jquery 实现多文件上传预览与删除功能

本教程详细介绍了如何使用 HTML、CSS 和 jQuery 构建一个用户友好的多文件上传界面。该界面支持实时预览图片和 PDF 文件,并允许用户在上传前删除不需要的文件,同时兼顾了前端交互逻辑和样式设计,为后端文件处理奠定了基础。

在现代 Web 应用中,用户上传多个文件(如图片、文档)并能实时预览和管理这些文件是常见的需求。本教程将指导您如何利用 jQuery 实现一个功能完善的多文件上传组件,该组件不仅提供文件预览,还允许用户在提交前删除已选择的文件,提升用户体验。

核心功能概览

我们将构建的组件具备以下核心功能:

  1. 多文件选择:通过一个隐藏的 <input type="file" multiple> 元素实现。
  2. 实时预览:当用户选择文件后,立即在页面上显示图片的缩略图或 PDF 文件的通用图标。
  3. 文件类型支持:支持常见的图片格式(JPEG, JPG, PNG)和 PDF 文件。
  4. 文件删除:每个预览项都带有一个删除按钮,允许用户移除不需要的文件。
  5. 文件数量限制:通过 data-max_length 属性控制最大可上传文件数量。

1. HTML 结构

首先,我们需要定义页面的基本 HTML 结构,包括上传按钮和用于显示文件预览的容器。

<form action="#" method="post" enctype="multipart/form-data">
  <div class="col-lg-12 mt-4">
    <label for="files">上传文件 (支持多文件)</label>
    <div class="upload__box">
      <div class="upload__btn-box">
        <label class="upload__btn">
          选择文件
          <input type="file" multiple="" id="files" name="files[]" data-max_length="20" class="upload__inputfile" accept="image/jpeg, image/jpg, image/png, application/pdf">
        </label>
      </div>
      <div class="upload__img-wrap"></div>
    </div>
  </div>
  <!-- 您可以在此处添加一个提交按钮 -->
  <!-- <button type="submit">上传</button> -->
</form>

<!-- 引入 jQuery 库,通常放在 </body> 标签之前 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
登录后复制

结构说明:

  • upload__box:整个上传区域的容器。
  • upload__btn-box:包含上传按钮的容器。
  • upload__btn:自定义的上传按钮样式,通过 label 标签关联到隐藏的 input。
  • upload__inputfile:实际的文件输入框。
    • multiple="":允许选择多个文件。
    • id="files" 和 name="files[]":用于后端接收文件数组。
    • data-max_length="20":自定义属性,用于前端限制最大上传文件数量。
    • accept="image/jpeg, image/jpg, image/png, application/pdf":限制可选的文件类型。
  • upload__img-wrap:用于显示文件预览的容器。

2. CSS 样式

为了美化上传界面并隐藏原生文件输入框,我们需要添加一些 CSS 样式。

<style>
.upload__box {
  padding-top: 10px;
}

.upload__inputfile {
  width: 0.1px;
  height: 0.1px;
  opacity: 0;
  overflow: hidden;
  position: absolute;
  z-index: -1;
}

.upload__btn {
  display: inline-block;
  font-weight: 600;
  color: #fff;
  text-align: center;
  min-width: 116px;
  padding: 5px;
  transition: all 0.3s ease;
  cursor: pointer;
  border: 2px solid;
  background-color: #4045ba;
  border-color: #4045ba;
  border-radius: 10px;
  line-height: 26px;
  font-size: 14px;
}

.upload__btn:hover {
  background-color: unset;
  color: #4045ba;
  transition: all 0.3s ease;
}

.upload__btn-box {
  margin-bottom: 0px;
}

.upload__img-wrap {
  display: flex;
  flex-wrap: wrap;
  margin: 0 -10px;
}

.upload__img-box {
  width: 200px; /* 预览项宽度 */
  padding: 0 10px;
  margin-bottom: 0px;
}

.upload__img-close {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background-color: rgba(0, 0, 0, 0.5);
  position: absolute;
  top: 10px;
  right: 10px;
  text-align: center;
  line-height: 24px;
  z-index: 1;
  cursor: pointer;
}

.upload__img-close:after {
  content: '\2716'; /* X 符号 */
  font-size: 14px;
  color: white;
}

.img-bg {
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
  position: relative;
  padding-bottom: 100%; /* 保持正方形比例 */
}
</style>
登录后复制

样式说明:

  • upload__inputfile:设置为 opacity: 0 和 position: absolute 来隐藏原生文件输入框,并通过 label 触发其点击事件。
  • upload__btn:自定义了上传按钮的样式,使其看起来更友好。
  • upload__img-wrap:使用 Flexbox 布局来排列预览图片。
  • upload__img-box:每个文件预览项的容器。
  • img-bg:用于显示图片预览的背景,通过 padding-bottom: 100% 技巧创建响应式的正方形区域。
  • upload__img-close:预览图片上的删除按钮样式。

3. JavaScript 逻辑 (jQuery)

核心功能将通过 jQuery 实现,包括文件选择监听、预览生成和文件删除。

AISEO
AISEO

AI创作对SEO友好的文案和文章

AISEO 56
查看详情 AISEO
<script>
$(document).ready(function () {
  ImgUpload(); // 初始化上传功能

  function ImgUpload() {
    var imgWrap = "";
    var imgArray = []; // 用于存储已选择文件的数组

    $('.upload__inputfile').each(function () {
      $(this).on('change', function (e) {
        imgWrap = $(this).closest('.upload__box').find('.upload__img-wrap');
        var maxLength = $(this).attr('data-max_length'); // 获取最大文件数量限制

        var files = e.target.files;
        var filesArr = Array.prototype.slice.call(files); // 将 FileList 转换为数组
        var iterator = 0;

        filesArr.forEach(function (f, index) {
          // 检查文件数量是否超过限制
          if (imgArray.length >= maxLength) {
            alert('最多只能上传 ' + maxLength + ' 个文件。');
            return false;
          }

          // 将文件添加到 imgArray
          imgArray.push(f);

          var reader = new FileReader();
          reader.onload = function (e) {
            var html = "";
            // 根据文件类型生成不同的预览 HTML
            if (f.type === 'application/pdf') {
              // PDF 文件显示通用图标
              html = "<div class='upload__img-box'>" +
                     "<div style='background-image: url(" + e.target.result + ")' data-number='" + $(".upload__img-close").length + "' data-file='" + f.name + "' class='img-bg'>" +
                     "<div class='upload__img-close'></div>" +
                     "<img src='https://cdn-icons-png.flaticon.com/128/337/337946.png' style='width: 100%; height: 100%; object-fit: contain; padding: 10px;'>" + // PDF 图标
                     "</div>" +
                     "</div>";
            } else {
              // 图片文件直接显示预览
              html = "<div class='upload__img-box'>" +
                     "<div style='background-image: url(" + e.target.result + ")' data-number='" + $(".upload__img-close").length + "' data-file='" + f.name + "' class='img-bg'>" +
                     "<div class='upload__img-close'></div>" +
                     "</div>" +
                     "</div>";
            }
            imgWrap.append(html); // 将预览添加到容器
            iterator++;
          }
          reader.readAsDataURL(f); // 读取文件内容为 Data URL
        });
        // 清空文件输入框,以便再次选择相同文件时能触发 change 事件
        $(this).val('');
      });
    });

    // 监听删除按钮点击事件
    $('body').on('click', ".upload__img-close", function (e) {
      var fileToRemove = $(this).parent().data("file"); // 获取要删除的文件名
      // 从 imgArray 中移除对应文件
      for (var i = 0; i < imgArray.length; i++) {
        if (imgArray[i] && imgArray[i].name === fileToRemove) {
          imgArray.splice(i, 1);
          break;
        }
      }
      $(this).parent().parent().remove(); // 移除预览 DOM 元素
    });
  }
});
</script>
登录后复制

JavaScript 逻辑说明:

  1. $(document).ready(function () { ImgUpload(); });: 页面加载完成后调用 ImgUpload 函数初始化功能。
  2. ImgUpload() 函数:
    • imgArray = []:一个全局数组,用于存储用户选择的所有 File 对象。这个数组最终可以用于通过 AJAX 发送到后端。
    • 文件选择监听 (.upload__inputfile').on('change', ...):
      • 获取 data-max_length 属性来限制文件数量。
      • e.target.files 获取用户选择的文件列表。
      • 将 FileList 转换为数组 filesArr,方便遍历。
      • 遍历 filesArr 中的每个文件:
        • 文件数量检查:在添加新文件前,检查 imgArray.length 是否已达到 maxLength。
        • imgArray.push(f):将当前文件对象添加到 imgArray。
        • FileReader:用于异步读取文件内容。
          • reader.onload:当文件读取完成后触发。
          • 根据 f.type 判断文件类型:
            • 如果是 application/pdf,则显示一个预设的 PDF 图标。
            • 否则(假定是图片),将 e.target.result (Data URL) 作为背景图片显示。
          • 生成的 HTML 包含一个 data-file 属性,存储文件名,用于后续删除操作。
          • imgWrap.append(html):将生成的预览 HTML 添加到页面。
        • reader.readAsDataURL(f):开始读取文件内容。
      • $(this).val(''):清空文件输入框的值,这样即使再次选择相同的文件,change 事件也能被触发。
    • 文件删除监听 ($('body').on('click', ".upload__img-close", ...)):
      • 使用事件委托 ($('body').on(...)) 来监听动态生成的删除按钮的点击事件。
      • $(this).parent().data("file"):获取要删除的文件名。
      • 遍历 imgArray,找到匹配文件名的文件并使用 splice 移除。
      • $(this).parent().parent().remove():从 DOM 中移除对应的预览元素。

4. 注意事项

  • 后端处理: 本教程主要关注前端交互。当用户最终提交表单时,您需要通过 AJAX 将 imgArray 中的文件发送到后端(例如 Laravel)。在 Laravel 中,您可以通过 FormData 对象来处理文件上传。

    // 示例:使用 FormData 和 AJAX 发送文件
    var formData = new FormData();
    for (var i = 0; i < imgArray.length; i++) {
        formData.append('files[]', imgArray[i]);
    }
    // 假设您还有其他表单数据
    // formData.append('other_field', $('#other_field_id').val());
    
    $.ajax({
        url: '/upload-endpoint', // 您的后端上传接口
        type: 'POST',
        data: formData,
        processData: false, // 告诉 jQuery 不要处理数据
        contentType: false, // 告诉 jQuery 不要设置 Content-Type 请求头
        success: function(response) {
            console.log('上传成功', response);
            // 处理成功后的逻辑
        },
        error: function(xhr, status, error) {
            console.error('上传失败', error);
            // 处理失败后的逻辑
        }
    });
    登录后复制
  • 文件类型与大小验证:

    • 前端的 accept 属性和 JavaScript 检查只是初步的用户体验优化,绝不能替代后端验证。后端必须对文件类型、大小、数量进行严格验证,以防止恶意文件上传和服务器资源滥用。
    • 您可以在 FileReader 之前添加更多 JavaScript 验证,例如检查文件大小。
  • 用户体验:

    • 考虑添加上传进度条或加载指示器,尤其是在文件较大或网络较慢的情况下。
    • 对错误情况(如上传失败、文件类型不匹配)提供清晰的用户反馈。
  • 安全性: 永远不要相信来自前端的数据。所有文件上传都必须在后端进行严格的验证和安全检查。

总结

通过结合 HTML 结构、CSS 样式和 jQuery 提供的强大 DOM 操作能力,我们成功构建了一个功能丰富且用户友好的多文件上传组件。这个组件不仅提供了实时预览和删除功能,还通过 imgArray 有效地管理了待上传的文件,为后续的后端集成奠定了坚实的基础。您可以根据自己的项目需求进一步扩展和优化此组件,例如添加拖拽上传、进度显示等高级功能。

以上就是使用 jQuery 实现多文件上传预览与删除功能的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号