如何在JavaScript中根据上传文件类型显示单个预览
解决方案:根据文件类型显示单一预览
你的核心问题在于当前代码同时为图片和视频元素设置了数据源,且通过file_picker.value提取扩展名的方式不可靠(浏览器会返回 fakepath,且扩展名不如MIME类型准确)。以下是修改方案:
关键改进点
- 存储文件时同时保存MIME类型,而非仅依赖扩展名判断
- 根据MIME类型动态显示/隐藏图片或视频预览元素
- 初始化和清空时统一处理预览元素的显示状态
修改后的代码
HTML(调整初始隐藏状态)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <link rel="stylesheet" href="/styles/index.css"> </head> <body id="upload_body"> <div class="upload_container"> <div class="container"> <input type="file" id="file_picker" accept="image/*,video/mp4"><br> <div class="preview-container"> <button type="button" id="button_clear" style="display:none;">CLEAR</button><br> <!-- 初始隐藏预览元素 --> <img id="image" src="" height="300px" width="auto" style="display:none;"><br> <video id="video" src="" height="300px" width="auto" autoplay="true" loop muted style="display:none;"></video> </div> </div> <h3 class="lead"> Follow Us <br><br> <a href="https://twitter.com/DevTopia_"> <img src="/assets/twitter.png" alt="twitter profile link" height="32px"/> </a> <a href="https://discord.gg/GAHDdWyj"> <img src="/assets/discord.png" alt="discord profile link" height="32px"/> </a> </h3> </div> <script type="application/javascript" src="/js/file_picker.js"></script> <script type="application/javascript" src="/js/content_script.js"></script> </body> </html>
JavaScript(核心修改部分)
function storage_onChanged(changes, areaName) { let settings = {}; if (areaName == "local") { if (changes.image_data_url) { settings.image_data_url = changes.image_data_url.newValue ?? ""; } if (changes.image_filename) { settings.image_filename = changes.image_filename.newValue ?? "none"; } if (changes.file_type) { settings.file_type = changes.file_type.newValue ?? ""; } } set_preview(settings); } // 重命名为更准确的函数名 function set_preview(settings) { const image = document.getElementById("image"); const video = document.getElementById("video"); const clearBtn = document.getElementById("button_clear"); // 先隐藏所有预览元素和按钮 image.style.display = "none"; video.style.display = "none"; clearBtn.style.display = "none"; if (!settings.image_data_url) return; // 根据MIME类型判断显示哪个预览 if (settings.file_type.startsWith("image/")) { image.src = settings.image_data_url; image.alt = settings.image_filename; image.style.display = "block"; clearBtn.style.display = "block"; } else if (settings.file_type.startsWith("video/")) { video.src = settings.image_data_url; video.alt = settings.image_filename; video.style.display = "block"; clearBtn.style.display = "block"; } } function remove_image() { chrome.storage.local.remove(["image_data_url", "image_filename", "file_type"]); } function store_image() { if (this.files.length > 0) { const file = this.files[0]; const reader = new FileReader(); reader.addEventListener("load", () => { chrome.storage.local.set({ image_data_url: reader.result, image_filename: file.name, file_type: file.type // 新增存储文件MIME类型 }); }); reader.readAsDataURL(file); } } // Initialization chrome.storage.local.get(["image_data_url", "image_filename", "file_type"]).then((items) => { set_preview({ image_data_url: items.image_data_url ?? "", image_filename: items.image_filename ?? "none", file_type: items.file_type ?? "" }); }); // Event Listeners const file_picker = document.querySelector("#file_picker"); if (file_picker) { file_picker.addEventListener("change", store_image); } const button_clear = document.getElementById("button_clear"); if (button_clear) { button_clear.addEventListener("click", remove_image); } chrome.storage.onChanged.addListener(storage_onChanged);
为什么这样修改?
- MIME类型更可靠:直接使用File对象的
type属性判断文件类型,比通过扩展名判断更准确,避免了扩展名伪造或大小写问题 - 统一状态管理:每次设置预览前先隐藏所有元素,确保不会同时显示两个预览
- 按钮状态同步:只有当有预览内容时才显示清空按钮,提升用户体验
内容的提问来源于stack exchange,提问作者Klaus
相关产品推荐
相关产品推荐

