未选文件触发Bootstrap警告后后续弹窗失效问题排查
问题:未选文件警告弹窗阻断后续所有弹窗显示
当未选择任何文件就点击Send ☞按钮时,页面会弹出Bootstrap警告提示「No files to upload.」,但该弹窗会导致后续所有弹窗(如文件上传成功、文件已存在等)无法正常显示。而触发文件已存在这类错误弹窗时,不会影响后续弹窗的展示,询问该未选文件警告阻断其他弹窗的原因。
相关代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Androp</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous"> </head> <body> <div class="container-fluid"> <p> <h1>Androp - Send to [...] MBP</h1> </p> <div class="input-group mb-3"> <button class="btn btn-outline-primary" type="button" onclick="send()">Send ☞</button> <input type="file" class="form-control" id="fileSelector"> </div> <div id="alerts"></div> <div class="text-center"> <div id="spinny" class="spinner-border" style="width: 3rem; height: 3rem; visibility: hidden;"></div> </div> </div> <script src="/socket.io/socket.io.js"></script> <script> const socket = io() const engine = socket.io.engine let maxSize = 0 let sending = false socket.on("disconnect", (reason) => { alert(`Disconnected from laptop! Check your internet or refresh the page. 💀 (${reason})`, "warning") }) engine.on("close", reason => { console.log(reason) }) socket.emit("getMaxSize", (size) => { return maxSize = size }) const alert = (message, type) => { const wrapper = document.createElement('div') wrapper.innerHTML = [ `<div class="alert alert-${type} fade show" role="alert">`, ` <div>${message}</div>`, '</div>' ].join('') document.getElementById("alerts").append(wrapper) return bootstrap.Alert.getOrCreateInstance(wrapper) } function send() { if (sending) { return false } sending = true const file = document.getElementById("fileSelector").files[0] || false function close(alert) { setTimeout(() => { alert.close() }, 3500) } if (!file) { return close(alert("No files to upload.", "warning")) } if (file.size >= maxSize) { return close(alert(`File is bigger than ${Math.round(maxSize / (1024 ** 2))} MB`, "danger")) } document.getElementById("spinny").style.visibility = 'visible' socket.timeout(10000).emit("upload", file, file.name, file.size, (err, status) => { if(err) { return close(alert("Could not contact laptop within 10s, laptop might be in sleep mode. 💀", "warning")) } document.getElementById("spinny").style.visibility = 'hidden' sending = false return close(alert(status.message, status.success ? "success" : "danger")) }) } </script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.5/dist/umd/popper.min.js" integrity="sha384-Xe+8cL9oJa6tN/veChSP7q+mnSPaj5Bcu9mPX5F5xIGE0DVittaqT5lorf0EI7Vk" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.min.js" integrity="sha384-ODmDIVzN+pFdexxHEHFBQH3/9/vQ9uori45z4JjnFsRydbmQbmL5t1tQ0culUzyK" crossorigin="anonymous"></script> </body> </html>
问题原因
核心问题是**sending状态变量未被正确重置**:
- 执行未选文件分支时,
send()函数开头已将sending设为true,随后直接return close(alert(...))退出函数,导致sending一直保持true状态。 - 后续点击
Send ☞按钮时,函数开头的if (sending) { return false }会直接拦截所有操作,连弹窗逻辑都无法触发,自然看不到后续弹窗。 - 而文件已存在这类场景属于上传回调分支,代码里明确执行了
sending = false重置状态,所以后续操作不受影响。
修复方案
在未选文件、文件大小超限以及上传超时的分支里,退出前重置sending为false即可:
function send() { if (sending) { return false } sending = true const file = document.getElementById("fileSelector").files[0] || false function close(alert) { setTimeout(() => { alert.close() }, 3500) } if (!file) { sending = false; // 重置状态 return close(alert("No files to upload.", "warning")) } if (file.size >= maxSize) { sending = false; // 重置状态 return close(alert(`File is bigger than ${Math.round(maxSize / (1024 ** 2))} MB`, "danger")) } document.getElementById("spinny").style.visibility = 'visible' socket.timeout(10000).emit("upload", file, file.name, file.size, (err, status) => { if(err) { sending = false; // 重置超时状态 return close(alert("Could not contact laptop within 10s, laptop might be in sleep mode. 💀", "warning")) } document.getElementById("spinny").style.visibility = 'hidden' sending = false return close(alert(status.message, status.success ? "success" : "danger")) }) }
内容的提问来源于stack exchange,提问作者WhatTheClown
相关产品推荐
相关产品推荐

