添加多个文件而不刷新当前文件的解决方法(HTML、JS)

Posted

技术标签:

【中文标题】添加多个文件而不刷新当前文件的解决方法(HTML、JS)【英文标题】:Workaround for adding multiple files without refreshing the current ones (HTML, JS) 【发布时间】:2021-11-13 14:43:06 【问题描述】:

我有一个简单的<input>,它将multiple files 作为上传。 问题如下:对于每个上传的file(在我的情况下是它的图像),我还添加了一个<select> tag 来选择该图像的宽度和高度,例如,我首先选择 5 个图像并选择它们的width x height 来自<select> option 我想添加另一个图像,问题来了,在添加另一个图像<select> tag @对于之前添加的每个图像,987654329@ 都会刷新回 default value

这是我处理上传和预览的代码的 sn-p:

function loadFiles(event) 
    let imagesSection = document.getElementById("images-section");
    
    for (let i = 0; i < event.files.length; i++) 
        let image = new Image();
        image.src = URL.createObjectURL(event.files[i]);

        imagesSection.innerhtml += 
        "<div class=\"image-frame\">" +
            "<img src=\"" + image.src + "\">" +
            "<select id=\"image-options-" + i + "\" name=\"size\" id=\"image-size\" required>" +
                "<option value=\"\" selected disabled hidden>select size</option>" +
                "<option value=\"\" disabled>horizontal</option>" +
                "<option value=\"w10h15\">10cm x 15cm</option>" +
                "<option value=\"w13h15\">13cm x 18cm</option>" +
                "<option value=\"w20h15\">20cm x 25cm</option>" +
                "<option value=\"w20h15\">20cm x 30cm</option>" +
                "<option value=\"\" disabled>vertical</option>" +
                "<option value=\"w15h10\">15cm x 10cm</option>" +
                "<option value=\"w18h13\">18cm x 13cm</option>" +
                "<option value=\"w25h20\">25cm x 20cm</option>" +
                "<option value=\"w30h20\">30cm x 20cm</option>" +
            "</select>" +
        "</div>";
        //console.log(event.files[i]);
    
;
<!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, viewport-fit=cover">
        <link rel="stylesheet" href="root.css">
        <title>Images</title>
    </head>

    <body>
        <div class="container">
            <div class="print-section">
                <div id="images-section" class="images-section"></div>
                
                <div class="upload-section">
                    <input id="files-input" type="file" name="files" accept="image/*" multiple onchange="loadFiles(this)" value="" />
                </div>
            </div>
        </div>
    </body>
</html>

有没有办法在不重新上传以前的文件的情况下进行新的上传,以便保存width x height?如果不是,我最好的猜测是尝试添加一个包含选项值的数组,然后在再次上传后将它们分别添加到每个图像中。

【问题讨论】:

【参考方案1】:

这就是你不应该使用imagesSection.innerHTML +=的原因之一。

这里发生的是当前 DOM 被转换为 HTML,然后与要添加的字符串连接并再次解析为 DOM。在该步骤中,在 DOM 中表示为状态的所有内容都将丢失,例如输入元素的值、事件侦听器……。

new Image 已经创建了一个可以添加到 DOM 的 ImageElement

使用createElementappendChild

您还应该避免使用onchange="loadFiles(this)",而是使用addEventListener

你有两个id 用于你的select,并且ids 必须是唯一的,使用i od for 循环不会产生唯一的id

function createSizeSelectElement(id) 
    let select = document.createElement('select')
    // name should be unique for a form
    select.name = "size"

    // you have id twice and id has to be unique
    // select.id = "image-options-" + id
    // select.id = "image-size"
    select.required = true

    // here you should consider using a loop and appendChild too
    select.innerHTML =
      "<option value=\"\" selected disabled hidden>select size</option>" +
      "<option value=\"\" disabled>horizontal</option>" +
      "<option value=\"w10h15\">10cm x 15cm</option>" +
      "<option value=\"w13h15\">13cm x 18cm</option>" +
      "<option value=\"w20h15\">20cm x 25cm</option>" +
      "<option value=\"w20h15\">20cm x 30cm</option>" +
      "<option value=\"\" disabled>vertical</option>" +
      "<option value=\"w15h10\">15cm x 10cm</option>" +
      "<option value=\"w18h13\">18cm x 13cm</option>" +
      "<option value=\"w25h20\">25cm x 20cm</option>" +
      "<option value=\"w30h20\">30cm x 20cm</option>"
    return select


function loadFiles(event) 
  let imagesSection = document.getElementById("images-section");

  for (let i = 0; i < event.target.files.length; i++) 
    let image = new Image();
    image.src = URL.createObjectURL( event.target.files[i]);

    let info = document.createElement('div')
    info.classList.add('image-frame')

    info.appendChild(image)
    info.appendChild(createSizeSelectElement(i))
    
    imagesSection.appendChild(info)
  


document.getElementById('files-input').addEventListener('change',loadFiles)
<div class="container">
  <div class="print-section">
    <div id="images-section" class="images-section"></div>

    <div class="upload-section">
      <input id="files-input" type="file" name="files" accept="image/*" multiple value="" />
    </div>
  </div>
</div>

【讨论】:

感谢您的详细回答并指出所有细节,它就像一个魅力!

以上是关于添加多个文件而不刷新当前文件的解决方法(HTML、JS)的主要内容,如果未能解决你的问题,请参考以下文章

从当前 url 追加/删除锚名称而不刷新

在Angular 7中运行另一个Component的方法而不刷新当前页面?

刷新当前用户配置文件

单击添加按钮时,角度选择多个文件而不上传和上传

如何使用find命令实现只查当前目录,而不查其子目录

使用php表单将记录添加到mysql数据库而不离开/刷新页面