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

使用 jQuery 实现多文件(图片与PDF)上传预览及删除功能

DDD
发布: 2025-11-22 11:42:16
原创
128人浏览过

使用 jQuery 实现多文件(图片与PDF)上传预览及删除功能

本教程详细介绍了如何利用 jquery前端实现一个功能完善的多文件上传组件。该组件支持同时上传图片和pdf文件,并提供即时预览功能及便捷的删除操作。我们将从html结构、css样式到核心javascript逻辑进行全面讲解,旨在帮助开发者构建用户友好的文件上传界面。

在现代Web应用中,文件上传是一个常见且重要的功能。为了提升用户体验,实现文件上传的即时预览和便捷管理变得尤为关键。本教程将指导您如何使用 jQuery 和纯前端技术,构建一个支持多文件(包括图片和PDF)上传、实时预览及删除功能的组件。

1. 核心功能概述

我们将构建一个前端解决方案,实现以下核心功能:

  • 多文件选择: 用户可以通过一个输入字段选择多个文件。
  • 即时预览:
    • 对于图片文件,显示缩略图预览。
    • 对于PDF文件,显示一个代表PDF的通用图标作为占位符预览。
  • 文件删除: 用户可以从预览列表中删除已选择的文件,且该文件不会被提交到服务器。
  • 文件类型与数量限制: 支持预设文件类型(如JPG, PNG, PDF)和最大文件数量限制。

2. HTML 结构

首先,我们需要一个基础的HTML结构来承载文件上传按钮和预览区域。确保您的页面已引入 jQuery 库。

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<form action="" method="POST" enctype="multipart/form-data">
  <div class="col-lg-12 mt-4">
    <label for="files">{{ __('Upload Receipts/Bills (Multiple Document)') }}</label>
    <div class="upload__box">
      <div class="upload__btn-box">
        <label class="upload__btn">
          {{__('Upload Bills')}}
          <!-- 文件输入字段,multiple 属性允许选择多个文件 -->
          <!-- data-max_length 用于前端限制最大文件数量 -->
          <!-- accept 属性限制文件类型 -->
          <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>
</form>
登录后复制

结构解析:

  • <form> 标签:虽然本教程主要关注前端,但实际应用中文件会通过表单提交到后端。enctype="multipart/form-data" 是文件上传必需的。
  • <label>:为文件输入提供友好的文本标签。
  • <div class="upload__box">:整个上传组件的容器。
  • <div class="upload__btn-box">:包含自定义上传按钮的容器。
  • <label class="upload__btn">:自定义的上传按钮,通过样式美化隐藏的 <input type="file">。
  • <input type="file" multiple="" id="files" name="files[]" data-max_length="20" class="upload__inputfile" accept="image/jpeg, image/jpg, image/png, application/pdf">:
    • multiple:允许用户选择多个文件。
    • name="files[]":在提交时,后端会接收到一个名为 files 的文件数组。
    • data-max_length="20":一个自定义属性,用于在JavaScript中限制最大上传文件数量。
    • class="upload__inputfile":用于JS选择器,且用于CSS隐藏原生文件输入框。
    • accept:指定浏览器文件选择器中允许的文件类型。
  • <div class="upload__img-wrap">:这是一个关键容器,所有选择的文件预览将动态地添加到这里。

3. CSS 样式

为了提供更好的用户体验,我们需要为上传组件和文件预览添加样式。

易笔AI论文
易笔AI论文

专业AI论文生成,免费生成论文大纲,在线生成选题/综述/开题报告等论文模板

易笔AI论文 103
查看详情 易笔AI论文
<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 {
  /* 预览区域的 flex 布局 */
  display: flex;
  flex-wrap: wrap;
  margin: 0 -10px; /* 负边距抵消内部元素的 padding */
}

.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 {
  /* 删除按钮的 'x' 符号 */
  content: '\2716';
  font-size: 14px;
  color: white;
}

.img-bg {
  /* 预览图片的背景样式,用于显示图片缩略图或PDF占位图 */
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
  position: relative;
  padding-bottom: 100%; /* 保持正方形比例 */
}
</style>
登录后复制

样式解析:

  • .upload__inputfile:通过设置 width, height, opacity, position 等属性,将原生文件输入框隐藏,使其不可见但仍可点击。
  • .upload__btn:定义了自定义上传按钮的视觉风格。
  • .upload__img-wrap:使用 display: flex 和 flex-wrap: wrap 实现预览图片的自动换行布局。
  • .upload__img-box:定义每个文件预览框的尺寸和间距。
  • .upload__img-close:创建了一个圆形、半透明的删除按钮,并使用 :after 伪元素添加“X”符号。
  • .img-bg:这是一个关键样式,它利用 background-image 来显示图片的预览。padding-bottom: 100% 结合 position: relative 和 background-size: cover 可以创建响应式的正方形图片容器。

4. JavaScript 逻辑 (使用 jQuery)

这是实现文件选择、预览和删除功能的核心部分。

$(document).ready(function () {
  ImgUpload(); // 页面加载完成后调用初始化函数

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

    // 监听所有 .upload__inputfile 元素的 change 事件
    $('.upload__inputfile').each(function () {
      $(this).on('change', function (e) {
        var 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 转换为数组

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

            var reader = new FileReader(); // 创建 FileReader 对象
            reader.onload = function (e) {
              var html = "";
              // 根据文件类型生成不同的预览HTML
              if (f.type === 'application/pdf') {
                // PDF 文件预览:显示一个PDF图标作为占位符
                html = "<div class='upload__img-box'>" +
                         "<div style='background-image: url(" + e.target.result + ")' 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' alt='PDF Icon' style='width: 100%; height: 100%; object-fit: contain; padding: 10px;'>" +
                         "</div>" +
                       "</div>";
              } else {
                // 图片文件预览:显示图片缩略图
                html = "<div class='upload__img-box'>" +
                         "<div style='background-image: url(" + e.target.result + ")' data-file='" + f.name + "' class='img-bg'>" +
                           "<div class='upload__img-close'></div>" +
                         "</div>" +
                       "</div>";
              }
              imgWrap.append(html); // 将预览HTML添加到容器中
            }
            reader.readAsDataURL(f); // 读取文件内容为 Data URL
          }
        });
      });
    });

    // 监听 .upload__img-close 元素的点击事件,实现文件删除
    $('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中移除预览元素
    });
  }
});
登录后复制

JavaScript 逻辑解析:

  1. $(document).ready(function () { ... });: 确保DOM加载完成后再执行JS代码。
  2. ImgUpload() 函数: 封装了所有上传逻辑。
    • var imgArray = [];: 一个全局数组,用于存储用户选择的所有 File 对象。这个数组在实际提交时会用到。
    • 文件选择监听 (.upload__inputfile change 事件):
      • $(this).closest('.upload__box').find('.upload__img-wrap'): 动态获取当前文件输入框对应的预览容器,确保多个上传组件可以独立工作。
      • data-max_length:从HTML属性中读取最大文件数量限制。
      • e.target.files: 获取用户选择的文件列表(FileList 对象)。
      • Array.prototype.slice.call(files): 将 FileList 转换为标准的JavaScript数组,方便遍历。
      • 数量限制检查: if (imgArray.length >= maxLength) 检查当前已选择文件数量是否超过限制。
      • imgArray.push(f): 将当前文件对象添加到 imgArray 中。
      • FileReader:
        • var reader = new FileReader();: FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容。
        • reader.onload = function (e) { ... };: 当文件读取成功完成时触发。e.target.result 包含了文件的 Data URL(Base64编码)。
        • 文件类型判断: if (f.type === 'application/pdf') 用于区分图片和PDF。
          • PDF 预览: 对于PDF,由于浏览器无法直接生成缩略图,我们通过一个通用PDF图标 (<img>) 来作为占位符,并将其放置在 img-bg 容器内。background-image 此时虽然有值,但主要显示的是 <img> 元素。
          • 图片预览: 对于图片,直接将 Data URL 设置为 img-bg 的 background-image,利用CSS的 background-size: cover 来显示缩略图。
        • imgWrap.append(html);: 将生成的预览HTML片段添加到预览容器中。
        • reader.readAsDataURL(f);: 开始读取文件内容。
    • 文件删除监听 (.upload__img-close click 事件):
      • $('body').on('click', ".upload__img-close", function (e) { ... });: 使用事件委托,因为预览元素是动态添加的。
      • $(this).parent().data("file"): 获取父级 .img-bg 元素上存储的 data-file 属性值,即文件名。
      • 从 imgArray 中移除: 遍历 imgArray,找到匹配的文件名并使用 splice(i, 1) 将其移除。
      • $(this).parent().parent().remove();: 从DOM中移除整个 .upload__img-box 元素,即删除预览。

5. 注意事项

  • 后端集成: 本教程提供的解决方案是纯前端的。实际文件上传需要后端服务(如Laravel、Node.js、Python等)来接收 name="files[]" 提交的文件数组,并进行存储、验证等操作。前端 imgArray 存储的文件对象需要在表单提交时通过 FormData 对象发送。
  • 文件大小限制: data-max_length 仅是前端的数量限制。文件大小限制应在后端进行严格校验,以防止恶意上传大文件导致服务器资源耗尽。
  • 安全性: 客户端的文件类型 (accept 属性) 和数量限制 (data-max_length) 仅用于提升用户体验。所有文件上传都必须在服务器端进行严格的文件类型、大小、内容(如图片是否包含恶意代码)等验证,以确保应用安全。
  • 错误处理: 当前代码未包含错误处理,例如当文件读取失败或文件类型不符合 accept 规则时。在生产环境中,应添加适当的错误提示。
  • 用户体验优化: 对于大量文件或大文件,可以考虑添加上传进度条或加载指示器,以提升用户体验。
  • 兼容性: 确保 jQuery 版本和浏览器兼容性符合项目需求。

总结

通过本教程,您已经掌握了如何使用 jQuery、HTML和CSS构建一个功能强大的前端多文件上传预览组件。该组件不仅提供了直观的用户界面,还支持图片和PDF文件的预览,并允许用户在上传前管理(删除)已选择的文件。将其与您的后端框架(如Laravel)结合,即可实现完整的图片和文件上传解决方案。记住,前端验证是用户体验的保障,后端验证则是系统安全的基石。

以上就是使用 jQuery 实现多文件(图片与PDF)上传预览及删除功能的详细内容,更多请关注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号