HTML批量文件上传2——进度条显示

作者:私语茶馆

        非常多的云应用中需要上传文本,包括图片,文件等等,这些批量文件上传,往往涉及到进度条显示,多文件上传等,这里分享一个非常好的案例,来自BootStrapfriendly.com,方便大家开发产品时使用。

        已验证的场景:PHP+JavaScript; Servlet+JavaScript; 使用的环境:Tomcat

1.异步上传文件使用的基本概念

1.1.AJAX

进度条本质是用脚本控制ProgressBar的显示,其中会用到AJAX,AJAX有如下特征:

  • AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
  • AJAX 不是新的编程语言,而是一种使用现有标准的新方法。
  • AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
  • AJAX 不需要任何浏览器插件,但需要用户允许 JavaScript 在浏览器上执行。
  • XMLHttpRequest 只是实现 Ajax 的一种方式。

1.2. Form

<form id="upload_form" enctype="multipart/form-data" method="post">

enctype=“multipart/form-data”: 指form中包含二进制的文件形式

1.3.XMLHttpRequest

        XMLHttpRequest(XHR)对象用于与服务器后端服务做请求交互,可以在不刷新页面的情况下请求特定的URL,获取数据。允许网元在不影响用户操作的情况下,更新页面的局部内容,是AJAX的一种关键使用绩效。

       XMLHttpRequest可以支持多种协议,包括FTP, file等。

        如果需要处理消息事件,可以使用EventSource,如果是全双工的可以是WebSocket。

参考:XMLHttpRequest - Web API | MDN (mozilla.org)

1.2.项目结构优化-独立的Scripts脚本

        从项目结构上讲,Script最好是独立文件,可以使用<script src="myscripts.js"></script>来引入,这样可以保持HTML简洁。

        如下图所示:

创建Scripts脚本

HTML引用该脚本

Script脚本

注意事项:要独立一个InitialLoad,并通过window.οnlοad=initialLoad来指定,如果脚本不起作用,可以检查一下windows.onload有没有设置。

2.异步批量上传文件及进度条案例

        这里前台部分直接使用Bootstrapfriedly.com的案例,后台用的是Apach的fileupload组件实现多文件上传,URL部分不同。

2.1. 前台界面

<div class="ath_container tile-container "><div id="uploadStatus"></div><h2 style="margin-bottom:10px">AJAX File Upload with Progress Bar using JavaScript</h2><input type="file" id="fileUpload" multiple placeholder="choose file or browse" /> <!-- Add 'multiple' attribute for multiple file selection --><br><br><button onclick="uploadFiles()">Upload</button> <!-- Change function name --><div><table id="progressBarsContainer"><!-- Table rows will be dynamically added here --></table></div> <!-- Container for progress bars --><br>
</div>

说明点:

(1)这里没有直接使用Form,用button的Click来处理,后面在Script中使用AJAX的XMLHttpRequest提交表单。

(2)table id=progressBarsContainer做为占位符号,后续ajax发送请求后,用于增量显示图片文件状态用。

2.2. CSS风格文件

* {margin: 0px;padding: 0px;box-sizing: border-box;
}body {font-family: -apple-system, BlinkMacSystemFont, Roboto, Segoe UI,Helvetica Neue, Helvetica, Arial, sans-serif;margin: 0 auto;-webkit-font-smoothing: antialiased;box-sizing: border-box;color: 
#2f2f2f;line-height: 1.5;
}.ath_container {width: 740px;margin: 20px auto;padding: 0px 20px 0px 20px;
}.ath_container {width: 820px;border: 
#d7d7d7 1px solid;border-radius: 5px;padding: 10px 20px 10px 20px;box-shadow: 0 0 5px 
rgba(0, 0, 0, .3);/* border-radius: 5px; */
}#uploadStatus {color: 
#00e200;
}.ath_container a {text-decoration: none;color: 
#2f20d1;
}.ath_container a:hover {text-decoration: underline;
}.ath_container img {height: auto;max-width: 100%;vertical-align: middle;
}.ath_container .label {color: 
#565656;margin-bottom: 2px;
}.ath_container .message {padding: 6px 20px;font-size: 1em;color: 
rgb(40, 40, 40);box-sizing: border-box;margin: 0px;border-radius: 3px;width: 100%;overflow: auto;
}.ath_container .error {padding: 6px 20px;border-radius: 3px;background-color: 
#ffe7e7;border: 1px solid 
#e46b66;color: 
#dc0d24;
}.ath_container .success {background-color: 
#48e0a4;border: 
#40cc94 1px solid;border-radius: 3px;color: 
#105b3d;
}.ath_container .validation-message {color: 
#e20900;
}.ath_container .font-bold {font-weight: bold;
}.ath_container .display-none {display: none;
}.ath_container .inline-block {display: inline-block;
}.ath_container .float-right {float: right;
}.ath_container .float-left {float: left;
}.ath_container .text-center {text-align: center;
}.ath_container .text-left {text-align: left;
}.ath_container .text-right {text-align: right;
}.ath_container .full-width {width: 100%;
}.ath_container .cursor-pointer {cursor: pointer;
}.ath_container .mr-20 {margin-right: 20px;
}.ath_container .m-20 {margin: 20px;
}.ath_container table {border-collapse: collapse;border-spacing: 0;width: 100%;border: 1px solid 
#ddd;margin-top: 20px;
}.ath_container table th,
.ath_container table td {text-align: left;padding: 5px;border: 1px solid 
#ededed;width: 50%;
}tr:nth-child(even) {background-color: 
#f2f2f2
}.ath_container .progress {margin: 20px 0 0 0;width: 300px;border: 1px solid 
#ddd;padding: 5px;border-radius: 5px;
}.ath_container .progress-bar {width: 0%;height: 24px;background-color: 
#4CAF50;margin-top: 15px;border-radius: 12px;text-align: center;color: 
#fff;
}@media all and (max-width: 780px) {.ath_container {width: auto;}
}.ath_container input,
.ath_container textarea,
.ath_container select {box-sizing: border-box;width: 200px;height: initial;padding: 8px 5px;border: 1px solid 
#9a9a9a;border-radius: 4px;
}.ath_container input[type="checkbox"] {width: auto;vertical-align: text-bottom;
}.ath_container textarea {width: 300px;
}.ath_container select {display: initial;height: 30px;padding: 2px 5px;
}.ath_container button,
.ath_container input[type=submit],
.ath_container input[type=button] {padding: 8px 30px;font-size: 1em;cursor: pointer;border-radius: 25px;color: 
#ffffff;background-color: 
#6213d3;border-color: 
#9554f1 
#9172bd 
#4907a9;
}.ath_container input[type=submit]:hover {background-color: 
#f7c027;
}::placeholder {color: 
#bdbfc4;
}.ath_container label {display: block;color: 
#565656;
}@media all and (max-width: 400px) {.ath_container {padding: 0px 20px;}.ath_container {width: auto;}.ath_container input,.ath_container textarea,.ath_container select {width: 100%;}
}

2.3. JavaScript脚本

    function uploadFiles() {var fileInput = document.getElementById('fileUpload');var files = fileInput.files;//(1)校验图片文件,并上传for (var i = 0; i < files.length; i++) {var allowedExtensions = ['.jpg', '.jpeg', '.png', '.pdf', '.svg', '.zip', '.docx', '.xlsx'];var fileExtension = files[i].name.substring(files[i].name.lastIndexOf('.')).toLowerCase();if (allowedExtensions.includes(fileExtension)) {//(1.1)一次上传一个文件,并显示文件名和进度uploadFile(files[i]);} else {alert('Invalid file type: ' + fileExtension);}}}function uploadFile(file) {var formData = new FormData();formData.append('file', file);var progressBarContainer = document.createElement('div'); // Container for progress bar and file nameprogressBarContainer.className = 'progress-container';var fileName = document.createElement('div'); // Display file namefileName.className = 'file-name';fileName.textContent = file.name;//progressBarContainer.appendChild(fileName);var progressBar = document.createElement('div'); // Create a new progress bar elementprogressBar.className = 'progress-bar';progressBar.id = 'progressBar_' + file.name;progressBarContainer.appendChild(progressBar);var progressBarsContainer = document.getElementById('progressBarsContainer');var newRow = document.createElement('tr'); // Create a new table rowvar newCell = document.createElement('td'); // Create a new table cellvar newCell2 = document.createElement('td'); // Create a new table cellnewCell.appendChild(fileName);newCell2.appendChild(progressBarContainer);newRow.appendChild(newCell);newRow.appendChild(newCell2);progressBarsContainer.appendChild(newRow);var xhr = new XMLHttpRequest();xhr.upload.addEventListener('progress', function(event) {if (event.lengthComputable) {var percent = Math.round((event.loaded / event.total) * 100);progressBar.style.width = percent + '%';progressBar.innerHTML = percent + '%';}});xhr.addEventListener('load', function(event) {var uploadStatus = document.getElementById('uploadStatus');uploadStatus.innerHTML = event.target.responseText;// Reset the input field of type "file"document.getElementById('fileUpload').value = '';});xhr.open('POST', 'upload.do', true);xhr.send(formData);}

关键点:

  • 这里的文件上传是一个一个上传的,上传一个显示一个状态,上传完成后,显示全部文件的状态。
  • xhr.open('post', 'upload.do',true); URL需要看本身后台发布的URL,我这里测试的是一个Servlet后台。

3.效果图

        上传前

上传后

4.相关章节

HTML批量文件上传1——图像预览方式_html上传多张图片并预览-CSDN博客

完整的项目下载(待后续补充):

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3019209.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

C++ | Leetcode C++题解之第76题最小覆盖子串

题目&#xff1a; 题解&#xff1a; class Solution { public:unordered_map <char, int> ori, cnt;bool check() {for (const auto &p: ori) {if (cnt[p.first] < p.second) {return false;}}return true;}string minWindow(string s, string t) {for (const au…

AI中转计费平台系统源码

AI中转计费平台系统源码 源码免费下载地址抄笔记 (chaobiji.cn)

ChIP-seq or CUTTag,谁能hold住蛋白质与DNA互作主战场?

DNA与蛋白质的相互作用作为表观遗传学中的一个重要领域&#xff0c;对理解基因表达调控、DNA复制与修复、表观遗传修饰&#xff08;组蛋白修饰&#xff09;及染色质结构等基本生命过程至关重要。 自1983年James Broach首次公布染色质免疫共沉淀&#xff08;ChIP&#xff09;技…

Ubuntu18.04 安装 anconda

anaconda官网 bash Anaconda3-2021.11-Linux-x86_64.sh一直回车&#xff0c;输入yes 选择安装目录 是否希望更新shell配置文件以自动初始化conda

STM32快速入门(定时器之输入捕获)

STM32快速入门&#xff08;定时器之输入捕获&#xff09; 前言 本节主要讲解STM32利用通用定时器&#xff0c;在输入引脚出现指定电平跳变时&#xff0c;将CNT的值锁存到CCR寄存器当中&#xff0c;从而计算PWM波形的频率、占空比、脉冲间隔、电平持续时间等。其功能的应用有&…

【转载】SAP MM培训事务代码

有需要的赶快收藏起来&#xff01;&#xff01;&#xff01;

4diacIDE同时编译不同版本踩坑记录

4diac不同版本依赖插件版本及jdk版本是不同的&#xff0c;当你需要搭建不同版本4diacIDE开发环境时&#xff0c;就会出现各种问题。最近一个月github上项目提交记录比较多&#xff0c;出现了不少坑。以下记录下此背景下的解决方法&#xff1a; 1、首先由于.target依赖的eclipse…

实战Java虚拟机-基础篇

JVM的组成 一、自动垃圾回收 1.Java的内存管理 Java中为了简化对象的释放&#xff0c;引入了自动的垃圾回收&#xff08;Garbage Collection简称GC&#xff09;机制。通过垃圾回收器来对不再使用的对象完成自动的回收&#xff0c;垃圾回收器主要负责对堆上的内存进行回收。其…

Win11任务栏通知很不明显的解决方案

Win11流行起来后&#xff0c;不少用户抱怨Win11的任务栏通知闪烁的颜色很不明显&#xff0c;经常微信来消息了看不到。虽然有右下角的微信图标会闪烁&#xff0c;但是提醒舒适度还是觉得不如Win10舒服显眼。 默认的颜色是这样子的&#xff0c;可以看得出Win11的任务栏提醒颜…

推荐5个AI工具平替GPT

随着AI技术的快速发展&#xff0c;AI写作正成为创作的新风口。但是面对GPT-4这样的国际巨头&#xff0c;国内很多小伙伴往往望而却步&#xff0c;究其原因&#xff0c;就是它的使用门槛高&#xff0c;还有成本的考量。 不过&#xff0c;随着GPT技术的火热&#xff0c;国内也涌…

Jetpack Compose(一

Intellij IDEA构建Android开发环境 IntelliJ IDEA 2023.2.1 Android开发变化 IDEA配置使用Gradle 新建Compose工程&#xff0c;取名ComposeStudy 可以看到的是IDEA为项目初始化了部分代码 使用Compose开发不再需要使用xml文件来设计布局了 Compose中的Text也不同于Android V…

JAVA语言程序设计1(第七章)

一、编程思想 1. 面向过程&#xff1a; (1) 面向过程&#xff1a;将问题分为第一步、第二步、第三步... 直到问题解决 (2) 问题&#xff1a;解决小业务相对比较简单&#xff0c;但是面对复杂业务时&#xff0c;相对不好处理 2. 面向对象&#xff1a; (1) 面向对象&#…

Windows10环境搭建http服务器

我 的 个 人 主 页&#xff1a;&#x1f449;&#x1f449; 失心疯的个人主页 &#x1f448;&#x1f448; 入 门 教 程 推 荐 &#xff1a;&#x1f449;&#x1f449; Python零基础入门教程合集 &#x1f448;&#x1f448; 虚 拟 环 境 搭 建 &#xff1a;&#x1f449;&…

TikTok营销策略解析:7大关键要素打造品牌影响力

TikTok作为近年来迅速崛起的短视频社交平台&#xff0c;已经成为全球范围内品牌营销的重要阵地。对于品牌而言&#xff0c;如何在TikTok上有效地开展营销活动&#xff0c;吸引目标受众的注意力&#xff0c;提升品牌知名度和影响力&#xff0c;是摆在他们面前的重要课题。本文No…

联发科技发布天玑9300+旗舰5G生成式AI芯片 | 最新快讯

5 月 7 日消息&#xff0c;联发科技今天举办了天玑开发者大会 2024。大会上&#xff0c;联发科技开启了“天玑 AI 先锋计划”&#xff0c;联合业界生态企业发布了《生成式 AI 手机产业白皮书》&#xff0c;分享了生成式 AI 端侧部署的解决方案“天玑 AI 开发套件”。同时&#…

图片在线压缩,base64在线转换

图片在线压缩&#xff0c;超级好用 图片压缩 - 在线免费图片压缩软件-迅捷压缩在线迅捷免费在线图片压缩软件提供JPG压缩、PNG压缩、BMP压缩功能,为用户解决如何压缩图片的问题,实现一键压缩图片大小,是一款专业的高质量图片压缩工具.https://yasuo.xunjiepdf.com/img/ base64…

五道数组习题,只过思路

建议先过一遍&#xff1a;保研机试前的最后七道数组题-CSDN博客 第一题&#xff1a; 88. 合并两个有序数组 - 力扣&#xff08;LeetCode&#xff09; ​ 跟合并两个有序链表类似&#xff0c; 快慢指针的用法&#xff0c;新建立一个数组&#xff0c;再将数组赋给nums1。 第…

快速搭建webase-front并且部署合约

PS: 因为我开发时候要用到fisco和webase-front,避免官方文档粘贴, 因此直接整理下面的笔记。开发的时候,好粘贴。1.搭建4节点联盟链 前提 curl 一种命令行工具 apt install -y openssl curl创建操作目录, 下载安装脚本 cd ~ && mkdir -p fisco && cd fisco…

Spring管理第三方依赖

在开发中&#xff0c;我们常需要根据业务需求导入我们需要的第三方依赖包&#xff0c;本文主要以导入druid数据库来连接池为案例讲解有关spring管理第三方依赖 目录 纯注解文件注入 1.在pom.xml中导入依赖 2.在com.lcyy包下建立一个config包用于配置类的实现 3.在config包下…

前端库推荐:markdown语法解析库-marked

这里写自定义目录标题 marked 介绍项目库应用展示微信md格式化工具 核心工作流setOptions 和 use()Options 选项renderer块级渲染方法 block-level行内渲染方法 inline-level hookspreprocess 处理之前postprocess 处理之后 官网扩展插件高亮自定义扩展 marked 介绍 Marked 是…