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>
相关推荐
Cyan_RA9几秒前
计算机网络面试题 — TCP连接如何确保可靠性?
前端·后端·面试
谢尔登几秒前
【CSS】层叠上下文和z-index
前端·css
鹏多多2 分钟前
前端复制功能的高效解决方案:copy-to-clipboard详解
前端·javascript
AryaNimbus4 分钟前
你不知道的 Cursor系列(三):再也不用死记硬背 Linux 命令,终端 Cmd+K 来帮你!
前端·ai编程·cursor
uhakadotcom5 分钟前
Rollup 从0到1:TypeScript打包完全指南
前端·javascript·面试
Mintopia11 分钟前
实时语音转写 + AIGC:Web 端智能交互的技术链路
前端·javascript·aigc
2503_9284115613 分钟前
9.15 ES6-变量-常量-块级作用域-解构赋值-箭头函数
前端·javascript·es6
Pedantic15 分钟前
SwiftUI ShareLink – 显示分享表单的使用
前端
徐小夕19 分钟前
花了一天时间,开源了一套精美且支持复杂操作的表格编辑器tablejs
前端·算法·github
Mintopia20 分钟前
Next.js 单元测试究竟该选 JTest 还是 Vitest?
前端·javascript·next.js