Chrome 94版本打开文件选择器触发浏览器冻结问题如何修复
问题修复方案
根因说明
Chrome 94.0.4606.81版本存在拖拽事件与隐藏文件输入框联动的渲染死循环bug,你的代码中两个逻辑触发了该bug:
dragover、dragenter两个高频触发事件共用了会修改DOM样式的onDragBegin函数,dragover每秒触发数十次,频繁触发DOM重绘- 整个拖拽区域包裹在label标签内部,拖拽事件冒泡与label的默认点击触发文件选择器的逻辑冲突,引发渲染进程卡死
具体修复步骤
- 拆分拖拽事件处理逻辑,
dragover事件仅做默认行为阻止和dropEffect设置,不操作DOM - 移除label包裹逻辑,单独为点击区域绑定点击事件主动触发文件选择器,避免label默认行为干扰
- 补充drop事件的文件有效性校验,避免空文件触发后续逻辑
- 所有拖拽事件都阻止冒泡,避免事件向上层传递触发意外逻辑
修改后代码
JavaScript
const fileInput = document.querySelector("#fileInput"); const dropArea = document.querySelector("#dropArea"); const upload = document.querySelector("#upload"); // dragover仅做基础处理,不操作DOM function onDragOver(e) { e.preventDefault(); e.stopPropagation(); e.dataTransfer.dropEffect = "copy"; } // 仅dragenter时修改样式 function onDragEnter(e) { e.preventDefault(); e.stopPropagation(); dropArea.classList.add("dropArea-highlight"); upload.classList.add("upload-highlight"); } function onDragLeave(e) { e.preventDefault(); e.stopPropagation(); // 仅当离开dropArea区域本身时才移除样式,避免子元素触发反复切换 if (e.target === dropArea) { dropArea.classList.remove("dropArea-highlight"); upload.classList.remove("upload-highlight"); } } function onDrop(e) { e.preventDefault(); e.stopPropagation(); dropArea.classList.remove("dropArea-highlight"); upload.classList.remove("upload-highlight"); // 校验是否有文件 const files = e.dataTransfer.files; if (!files || files.length === 0) return; fileInput.files = files; fileInput.dispatchEvent(new Event("change")); } async function onChangeFileInput() { const { files } = this; if (!files || files.length === 0) return; const url = "/api/har"; const formData = new FormData(); formData.append("harFile", files[0]); fetch(url, { method: "POST", body: formData, }).then(async (res) => { if (!res.ok) { const text = await res.text(); alert(text); } if (res.redirected) { window.location.href = res.url; } }); } // 点击区域主动触发文件选择器 dropArea.addEventListener('click', () => { fileInput.click(); }) dropArea.ondragover = onDragOver; dropArea.ondragenter = onDragEnter; dropArea.ondragleave = onDragLeave; dropArea.ondrop = onDrop; fileInput.addEventListener("change", onChangeFileInput);
HTML
<!DOCTYPE html> <html lang="en"> <head> <link rel="stylesheet" href="style.css"> <script src="upload.js" defer></script> </head> <body> <div class="upload" id="upload"> <div id="dropArea"> <img src="upload.svg" class="upload-icon" alt="上传图标"> <h3>Drag and drop or click</h3> <p>to upload your file</p> <input type="file" name="harFile" id="fileInput" accept=".har"> </div> </div> </body> </html>
CSS代码无需修改,保持原有逻辑即可。
内容的提问来源于stack exchange,提问作者marcelh
相关产品推荐
相关产品推荐

