2023-05-25 12:55:44
在线直播源码中,文件上传(包括图片上传)的传输速度计算可以通过监听上传进度事件来实现。以下是对代码的详细解析和传输速度计算的实现方法:
核心代码解析文件选择监听通过 input[type="file"] 监听用户选择的文件,获取文件对象:
document.querySelector("#file").addEventListener("change", function() { var file = document.querySelector("#file").files[0];});FormData 封装文件使用 FormData 对象封装文件数据,便于通过 AJAX 上传:
var formdata = new FormData();formdata.append("file", file);XMLHttpRequest 上传创建 XMLHttpRequest 对象,配置 POST 请求并发送 FormData:
var xhr = new XMLHttpRequest();xhr.open("post", "/");xhr.send(formdata);上传进度监听通过 xhr.upload.onprogress 事件获取已上传数据量(event.loaded)和总数据量(event.total),计算进度百分比:
xhr.upload.onprogress = function(event) { if (event.lengthComputable) { var percent = (event.loaded / event.total) * 100; document.querySelector("#progress .progress-item").style.width = percent + "%"; }};传输速度(单位:KB/s 或 MB/s)可通过记录 已上传数据量 和 时间差 动态计算。以下是扩展代码:
1. 添加速度计算变量let lastLoaded = 0; // 上次记录的已上传字节数let lastTime = Date.now(); // 上次记录的时间戳let speed = 0; // 实时速度(字节/秒)2. 修改进度事件回调在 onprogress 中计算速度并更新显示:
xhr.upload.onprogress = function(event) { if (event.lengthComputable) { // 计算进度百分比 var percent = (event.loaded / event.total) * 100; document.querySelector("#progress .progress-item").style.width = percent + "%"; // 计算传输速度 const now = Date.now(); const timeElapsed = (now - lastTime) / 1000; // 转换为秒 if (timeElapsed > 0) { speed = (event.loaded - lastLoaded) / timeElapsed; // 字节/秒 lastLoaded = event.loaded; lastTime = now; // 格式化速度(KB/s 或 MB/s) let formattedSpeed; if (speed > 1024 * 1024) { formattedSpeed = (speed / (1024 * 1024)).toFixed(2) + " MB/s"; } else { formattedSpeed = (speed / 1024).toFixed(2) + " KB/s"; } // 显示速度(可添加一个DOM元素展示) console.log("当前速度:", formattedSpeed); } }};3. 完整代码示例<!doctype html><html><head> <meta charset="UTF-8"> <title>文件上传速度计算</title> <style> #progress { height: 10px; width: 500px; border: 1px solid gold; position: relative; border-radius: 5px; } #progress .progress-item { height: 100%; position: absolute; left: 0; top: 0; background: chartreuse; border-radius: 5px; transition: width 0.3s linear; } #speed { margin-top: 10px; font-family: monospace; } </style></head><body> 文件上传框<br> <input type="file" id="file"><br> 显示进度条<br> <div id="progress"> <div class="progress-item"></div> </div> 上传速度:<span id="speed">0 KB/s</span><br> 上传结果:<span id="callback"></span> <script> let lastLoaded = 0; let lastTime = Date.now(); let speed = 0; document.querySelector("#file").addEventListener("change", function() { var file = document.querySelector("#file").files[0]; var formdata = new FormData(); formdata.append("file", file); var xhr = new XMLHttpRequest(); xhr.open("post", "/"); xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { document.querySelector("#callback").innerText = xhr.responseText; } }; xhr.upload.onprogress = function(event) { if (event.lengthComputable) { // 更新进度条 var percent = (event.loaded / event.total) * 100; document.querySelector("#progress .progress-item").style.width = percent + "%"; // 计算速度 const now = Date.now(); const timeElapsed = (now - lastTime) / 1000; if (timeElapsed > 0) { speed = (event.loaded - lastLoaded) / timeElapsed; lastLoaded = event.loaded; lastTime = now; // 格式化速度 let formattedSpeed; if (speed > 1024 * 1024) { formattedSpeed = (speed / (1024 * 1024)).toFixed(2) + " MB/s"; } else { formattedSpeed = (speed / 1024).toFixed(2) + " KB/s"; } document.querySelector("#speed").innerText = formattedSpeed; } } }; xhr.send(formdata); }); </script></body></html>关键点说明速度计算逻辑
通过 event.loaded 和时间差计算瞬时速度(字节/秒)。
动态更新 lastLoaded 和 lastTime 确保下次计算基于最新数据。
单位转换
将字节转换为 KB 或 MB,提升可读性(1 MB = 1024 KB,1 KB = 1024 字节)。
性能优化
避免频繁更新 DOM(如使用 requestAnimationFrame 节流),但此处直接更新影响较小。
通过以上方法,可以实时监控文件上传速度,优化用户体验。