html:文件上传-一次性可上传多个文件,将文件展示到页面(可删除

一、原始上传样式

1、效果

2、完整代码

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        /* 文件展示容器样式 */
        .file-preview-container {
            display: flex;
            flex-wrap: wrap;
            /* 换行 */
            gap: 10px;
            /* 小块之间的间距 */
            margin-top: 10px;
        }

        /* 文件小块样式 */
        .file-preview-item {
            display: flex;
            align-items: center;
            background-color: #f0f0f0;
            border: 1px solid #ccc;
            border-radius: 4px;
            padding: 5px 10px;
            font-size: 14px;
            white-space: nowrap;
            /* 防止文件名换行 */
        }

        /* 删除按钮样式 */
        .file-preview-item .delete-btn {
            margin-left: 10px;
            color: red;
            cursor: pointer;
            font-weight: bold;
        }
    </style>
</head>

<body>
    <form id="uploadForm" action="upload.php" method="post" enctype="multipart/form-data">
        <label for="files">选择多个文件:</label>
        <input type="file" name="files[]" id="files" multiple>
        <br><br>
        <!-- 文件展示区域 -->
        <div id="file-preview-container" class="file-preview-container"></div>
        <button type="submit">上传</button>
    </form>

    <script>
        document.addEventListener("DOMContentLoaded", function () {
            const fileInput = document.getElementById("files");
            const filePreviewContainer = document.getElementById("file-preview-container");
            const uploadForm = document.getElementById("uploadForm");

            // 存储选中的文件
            let selectedFiles = [];

            // 监听文件输入框的变化
            fileInput.addEventListener("change", function (event) {
                const files = Array.from(event.target.files); // 获取选中的文件列表
                // 清空之前的预览
                filePreviewContainer.innerHTML = "";
                selectedFiles = [];
                // 遍历文件并生成小块
                files.forEach((file) => {
                    // 创建文件小块
                    const fileItem = document.createElement("div");
                    fileItem.className = "file-preview-item";
                    fileItem.dataset.fileName = file.name; // 保存文件名作为标识
                    // 显示文件名
                    fileItem.innerHTML = `
                        ${file.name}
                        <span class="delete-btn" onclick="removeFile('${file.name}')">&times;</span>
                    `;
                    // 添加到预览容器
                    filePreviewContainer.appendChild(fileItem);
                    // 将文件存入数组
                    selectedFiles.push(file);
                });
            });

            // 删除文件的函数
            window.removeFile = function (fileName) {
                // 从数组中移除文件
                selectedFiles = selectedFiles.filter((file) => file.name !== fileName);

                // 从 DOM 中移除对应的小块
                const fileItem = document.querySelector(`.file-preview-item[data-file-name="${fileName}"]`);
                if (fileItem) {
                    fileItem.remove();
                }
            };

            // 拦截表单提交事件
            uploadForm.addEventListener("submit", function (event) {
                event.preventDefault(); // 阻止表单默认提交行为

                // 构造 FormData 对象
                const formData = new FormData();

                // 将选中的文件添加到 FormData 中
                selectedFiles.forEach((file, index) => {
                    formData.append("files[]", file); // 注意这里的键名要和服务器端一致
                });
                console.log(selectedFiles);
                // 使用 AJAX 提交文件
                // fetch("upload.php", {
                //     method: "POST",
                //     body: formData,
                // })
                //     .then(response => response.text())
                //     .then(data => {
                //         console.log("上传成功:", data);
                //         alert("文件上传成功!");
                //     })
                //     .catch(error => {
                //         console.error("上传失败:", error);
                //         alert("文件上传失败!");
                //     });
            });
        });
    </script>
</body>

</html>

二、扩展-隐藏原文件上传效果

1、效果

2、完整代码

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>文件上传</title>
    <style>
        /* 隐藏原生文件输入框 */
        #files {
            display: none;
        }

        /* 自定义按钮样式 */
        .custom-file-button,button {
            display: inline-block;
            padding: 10px 20px;
            background-color: #42b983;
            color: white;
            border-radius: 5px;
            cursor: pointer;
            font-size: 16px;
            border: none;
        }

        /* 文件展示容器样式 */
        .file-preview-container {
            display: flex;
            flex-wrap: wrap; /* 换行 */
            gap: 10px; /* 小块之间的间距 */
            margin-top: 10px;
        }

        /* 文件小块样式 */
        .file-preview-item {
            display: flex;
            align-items: center;
            background-color: #f0f0f0;
            border: 1px solid #ccc;
            border-radius: 4px;
            padding: 5px 10px;
            font-size: 14px;
            white-space: nowrap; /* 防止文件名换行 */
        }

        /* 删除按钮样式 */
        .file-preview-item .delete-btn {
            margin-left: 10px;
            color: red;
            cursor: pointer;
            font-weight: bold;
        }
    </style>
</head>

<body>
    <form id="uploadForm" action="upload.php" method="post" enctype="multipart/form-data">
        <!-- 自定义文件选择按钮 -->
        <label for="files" class="custom-file-button">选择文件</label>
        <input type="file" name="files[]" id="files" multiple>
        <br><br>

        <!-- 文件展示区域 -->
        <div id="file-preview-container" class="file-preview-container"></div>
        <br><br>
        <button type="submit">上传</button>
    </form>

    <script>
        document.addEventListener("DOMContentLoaded", function () {
            const fileInput = document.getElementById("files");
            const filePreviewContainer = document.getElementById("file-preview-container");
            const uploadForm = document.getElementById("uploadForm");

            // 存储选中的文件
            let selectedFiles = [];

            // 监听文件输入框的变化
            fileInput.addEventListener("change", function (event) {
                const files = Array.from(event.target.files); // 获取选中的文件列表
                // 清空之前的预览
                filePreviewContainer.innerHTML = "";
                selectedFiles = [];
                // 遍历文件并生成小块
                files.forEach((file) => {
                    // 创建文件小块
                    const fileItem = document.createElement("div");
                    fileItem.className = "file-preview-item";
                    fileItem.dataset.fileName = file.name; // 保存文件名作为标识
                    // 显示文件名
                    fileItem.innerHTML = `
                        ${file.name}
                        <span class="delete-btn" onclick="removeFile('${file.name}')">&times;</span>
                    `;
                    // 添加到预览容器
                    filePreviewContainer.appendChild(fileItem);
                    // 将文件存入数组
                    selectedFiles.push(file);
                });
            });

            // 删除文件的函数
            window.removeFile = function (fileName) {
                // 从数组中移除文件
                selectedFiles = selectedFiles.filter((file) => file.name !== fileName);

                // 从 DOM 中移除对应的小块
                const fileItem = document.querySelector(`.file-preview-item[data-file-name="${fileName}"]`);
                if (fileItem) {
                    fileItem.remove();
                }
            };

            // 拦截表单提交事件
            uploadForm.addEventListener("submit", function (event) {
                event.preventDefault(); // 阻止表单默认提交行为

                // 构造 FormData 对象
                const formData = new FormData();

                // 将选中的文件添加到 FormData 中
                selectedFiles.forEach((file, index) => {
                    formData.append("files[]", file); // 注意这里的键名要和服务器端一致
                });
                console.log(selectedFiles);
                // 使用 AJAX 提交文件
                // fetch("upload.php", {
                //     method: "POST",
                //     body: formData,
                // })
                //     .then(response => response.text())
                //     .then(data => {
                //         console.log("上传成功:", data);
                //         alert("文件上传成功!");
                //     })
                //     .catch(error => {
                //         console.error("上传失败:", error);
                //         alert("文件上传失败!");
                //     });
            });
        });
    </script>
</body>

</html>
相关推荐
陶甜也几秒前
threejs 实现720°全景图,;两种方式:环境贴图、CSS3DRenderer渲染
前端·vue.js·css3·threejs
上单带刀不带妹1 分钟前
解锁 JavaScript 模块化:ES6 Module 语法深度指南
开发语言·前端·javascript·es6
Kier41 分钟前
🚀 前端实战:优雅地实现一个通用Blob文件下载方法
前端·javascript·axios
前端Hardy41 分钟前
从生活场景学透 JavaScript 原型与原型链
前端·javascript
JiangJiang43 分钟前
🔥 第一次在 React 项目中用 UnoCSS,这些坑我都踩了
前端·vue.js·react.js
Hy小杨1 小时前
Vue3+高德地图实战:打造告警监控的一份指南
前端
Hy小杨1 小时前
el-table加了key导致页面滚动位置异常?这个优化方案让用户体验直线提升!
前端
旺仔牛仔QQ糖1 小时前
找不到模块“vite”。你的意思是要将 “moduleResolution“ 选项设置为 “node“,还是要将别名添加到 “paths“ 选项中?
前端
Uyker1 小时前
前端与后端主流框架分类及关键特性
前端·算法·django
GalaxyPokemon1 小时前
RPC - Response模块
java·前端·javascript