上传多张图片并将它们转换为base64?

huangapple go评论62阅读模式
英文:

Uploading multiple images and convert them to base64?

问题

I can help with the translation of the code. Here's the translated code:

<div class="form-group">
    <label for="product_photo_1">照片 1</label>
    <div class="custom-file">
        <input type="file" class="custom-file-input" id="product_photo_1" multiple />
        <label class="custom-file-label" for="product_photo_1" data-browse="选择">请选择文件...</label>
    </div>
    <div id="product_photo_1_result"></div>
</div>
<div class="form-group">
    <label for="product_photo_2">照片 2</label>
    <div class="custom-file">
        <input type="file" class="custom-file-input" id="product_photo_2" multiple />
        <label class="custom-file-label" for="product_photo_2" data-browse="选择">请选择文件...</label>
    </div>
    <div id="product_photo_2_result"></div>
</div>
<script>
    const convertBase64 = (file) => {
        return new Promise((resolve, reject) => {
            const fileReader = new FileReader();

            fileReader.readAsDataURL(file);

            fileReader.onload = () => {
                resolve(fileReader.result);
            };

            fileReader.onerror = (error) => {
                reject(error);
            };
        });
    };

    const uploadImage = async (event, id) => {
        const file = event.target.files[0];

        const base64 = await convertBase64(file);

        document.getElementById("product_photo_" + id + "_result").innerHTML += '<img src="' + base64 + '" class="img-thumbnail m-2" id="product_photo_' + id + '[]" style="height: 50px;" />';
    };

    document.getElementById("product_photo_1").addEventListener("change", (event) => {
        for (var index = 1; index <= document.getElementById("product_photo_1").files.length; index++) {
            uploadImage(event, 1);
        }
    });

    document.getElementById("product_photo_2").addEventListener("change", (event) => {
        for (var index = 1; index <= document.getElementById("product_photo_2").files.length; index++) {
            uploadImage(event, 2);
        }
    });
</script>

This code appears to be related to creating a form for uploading multiple images and displaying them as base64 encoded images using jQuery's POST.

英文:

I'm trying to create a form where you can upload multiple images using two file inputs, see the images as base64 and later submit them using jQuery's POST. The problem is that when I select 3 different images, I see only the last one 3 times. I guess the problem is in the for in the addEventListener - maybe it's not in the right place?

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

&lt;div class=&quot;form-group&quot;&gt;
&lt;label for=&quot;product_photo_1&quot;&gt;Photos 1&lt;/label&gt;
&lt;div class=&quot;custom-file&quot;&gt;
&lt;input type=&quot;file&quot; class=&quot;custom-file-input&quot; id=&quot;product_photo_1&quot; multiple /&gt;
&lt;label class=&quot;custom-file-label&quot; for=&quot;product_photo_1&quot; data-browse=&quot;Select&quot;&gt;Please, select a file...&lt;/label&gt;
&lt;/div&gt;
&lt;div id=&quot;product_photo_1_result&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;form-group&quot;&gt;
&lt;label for=&quot;product_photo_2&quot;&gt;Photos 2&lt;/label&gt;
&lt;div class=&quot;custom-file&quot;&gt;
&lt;input type=&quot;file&quot; class=&quot;custom-file-input&quot; id=&quot;product_photo_2&quot; multiple /&gt;
&lt;label class=&quot;custom-file-label&quot; for=&quot;product_photo_2&quot; data-browse=&quot;Select&quot;&gt;Please, select a file...&lt;/label&gt;
&lt;/div&gt;
&lt;div id=&quot;product_photo_2_result&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;script&gt;
const convertBase64 = (file) =&gt; {
return new Promise((resolve, reject) =&gt; {
const fileReader = new FileReader();
fileReader.readAsDataURL(file);
fileReader.onload = () =&gt; {
resolve(fileReader.result);
};
fileReader.onerror = (error) =&gt; {
reject(error);
};
});
};
const uploadImage = async (event, id) =&gt; {
const file = event.target.files[0];
const base64 = await convertBase64(file);
document.getElementById(&quot;product_photo_&quot; + id + &quot;_result&quot;).innerHTML += &#39;&lt;img src=&quot;&#39; + base64 + &#39;&quot; class=&quot;img-thumbnail m-2&quot; id=&quot;product_photo_&#39; + id + &#39;[]&quot; style=&quot;height: 50px;&quot; /&gt;&#39;;
};
document.getElementById(&quot;product_photo_1&quot;).addEventListener(&quot;change&quot;, (event) =&gt; {
for(var index = 1; index &lt;= document.getElementById(&quot;product_photo_1&quot;).files.length; index++) {
uploadImage(event, 1);
}
});
document.getElementById(&quot;product_photo_2&quot;).addEventListener(&quot;change&quot;, (event) =&gt; {
for(var index = 1; index &lt;= document.getElementById(&quot;product_photo_2&quot;).files.length; index++) {
uploadImage(event, 2);
}
});
&lt;/script&gt;

<!-- end snippet -->

答案1

得分: 2

uploadImage 函数中,你每次都传递了 event 参数并选择了第一个文件

const file = event.target.files[0];

相反,你可以将文件逐个传递给 uploadImage 函数。

这里是示例:

<div class="form-group">
  <label for="product_photo_1">Photos 1</label>
  <div class="custom-file">
    <input type="file" class="custom-file-input" id="product_photo_1" multiple />
    <label class="custom-file-label" for="product_photo_1" data-browse="Select">Please, select a file...</label>
  </div>
  <div id="product_photo_1_result"></div>
</div>
<div class="form-group">
  <label for="product_photo_2">Photos 2</label>
  <div class="custom-file">
    <input type="file" class="custom-file-input" id="product_photo_2" multiple />
    <label class="custom-file-label" for="product_photo_2" data-browse="Select">Please, select a file...</label>
  </div>
  <div id="product_photo_2_result"></div>
</div>
<script>
  const convertBase64 = (file) => {
    return new Promise((resolve, reject) => {
      const fileReader = new FileReader();

      fileReader.readAsDataURL(file);

      fileReader.onload = () => {
        resolve(fileReader.result);
      };

      fileReader.onerror = (error) => {
        reject(error);
      };
    });
  };

  const uploadImage = async (file, id) => {
  
    const base64 = await convertBase64(file);

    document.getElementById("product_photo_" + id + "_result").innerHTML += '<img src="' + base64 + '" class="img-thumbnail m-2" id="product_photo_' + id + '[]" style="height: 50px;" />';
  };

  document.getElementById("product_photo_1").addEventListener("change", (event) => {
   let files = document.getElementById("product_photo_1").files;
    for (let index = 0; index <= files.length; index++) {
      uploadImage(files[index], 1);
    }
  });

  document.getElementById("product_photo_2").addEventListener("change", (event) => {
  	let files = document.getElementById("product_photo_2").files;
    for (let index = 0; index <= document.getElementById("product_photo_2").files.length; index++) {
      uploadImage(files[index], 2);
    }
  });

</script>
英文:

In uploadImage function you are passing event argument and select first file every time

const file = event.target.files[0];

Instead you can pass files one by one to the uploadImage.

Here is the example:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

&lt;div class=&quot;form-group&quot;&gt;
&lt;label for=&quot;product_photo_1&quot;&gt;Photos 1&lt;/label&gt;
&lt;div class=&quot;custom-file&quot;&gt;
&lt;input type=&quot;file&quot; class=&quot;custom-file-input&quot; id=&quot;product_photo_1&quot; multiple /&gt;
&lt;label class=&quot;custom-file-label&quot; for=&quot;product_photo_1&quot; data-browse=&quot;Select&quot;&gt;Please, select a file...&lt;/label&gt;
&lt;/div&gt;
&lt;div id=&quot;product_photo_1_result&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;form-group&quot;&gt;
&lt;label for=&quot;product_photo_2&quot;&gt;Photos 2&lt;/label&gt;
&lt;div class=&quot;custom-file&quot;&gt;
&lt;input type=&quot;file&quot; class=&quot;custom-file-input&quot; id=&quot;product_photo_2&quot; multiple /&gt;
&lt;label class=&quot;custom-file-label&quot; for=&quot;product_photo_2&quot; data-browse=&quot;Select&quot;&gt;Please, select a file...&lt;/label&gt;
&lt;/div&gt;
&lt;div id=&quot;product_photo_2_result&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;script&gt;
const convertBase64 = (file) =&gt; {
return new Promise((resolve, reject) =&gt; {
const fileReader = new FileReader();
fileReader.readAsDataURL(file);
fileReader.onload = () =&gt; {
resolve(fileReader.result);
};
fileReader.onerror = (error) =&gt; {
reject(error);
};
});
};
const uploadImage = async (file, id) =&gt; {
const base64 = await convertBase64(file);
document.getElementById(&quot;product_photo_&quot; + id + &quot;_result&quot;).innerHTML += &#39;&lt;img src=&quot;&#39; + base64 + &#39;&quot; class=&quot;img-thumbnail m-2&quot; id=&quot;product_photo_&#39; + id + &#39;[]&quot; style=&quot;height: 50px;&quot; /&gt;&#39;;
};
document.getElementById(&quot;product_photo_1&quot;).addEventListener(&quot;change&quot;, (event) =&gt; {
let files = document.getElementById(&quot;product_photo_1&quot;).files;
for (let index = 0; index &lt;= files.length; index++) {
uploadImage(files[index], 1);
}
});
document.getElementById(&quot;product_photo_2&quot;).addEventListener(&quot;change&quot;, (event) =&gt; {
let files = document.getElementById(&quot;product_photo_2&quot;).files;
for (let index = 0; index &lt;= document.getElementById(&quot;product_photo_2&quot;).files.length; index++) {
uploadImage(files[index], 2);
}
});
&lt;/script&gt;

<!-- end snippet -->

答案2

得分: 0

In the event handlers, you are doing a loop, but you are not using the value of index per iteration:

document.getElementById("product_photo_1").addEventListener("change", (event) => {
    for (var index = 1; index <= document.getElementById("product_photo_1").files.length; index++) {
        uploadImage(event, 1); //passing only the event and an index
    }
});

document.getElementById("product_photo_2").addEventListener("change", (event) => {
    for (var index = 1; index <= document.getElementById("product_photo_2").files.length; index++) {
        uploadImage(event, 2); //passing only the event and the index
    }
});

And now, let's use index for all calls as well as clearing up when it's 0:

const uploadImage = async (event, id, index) => {
    let context = document.getElementById("product_photo_" + id + "_result");
    const file = event.target.files[index]; //we get the correct file;

    const base64 = await convertBase64(file);

    let template = '<img src="' + base64 + '" class="img-thumbnail m-2" id="product_photo_' + id + '[]" style="height: 50px;" />';

    if (index === 0) context.innerHTML = template; //clearing older values and adding the first element
    else context.innerHTML += template; //appending the (not first) element
};

Instead, you will need to pass the index as well, like this:

document.getElementById("product_photo_1").addEventListener("change", (event) => {
    for (var index = 0; index < document.getElementById("product_photo_1").files.length; index++) {
        uploadImage(event, 1, index);
    }
});

document.getElementById("product_photo_2").addEventListener("change", (event) => {
    for (var index = 0; index < document.getElementById("product_photo_2").files.length; index++) {
        uploadImage(event, 2, index);
    }
});
英文:

In the event handlers, you are doing a loop, but you are not using the value of index per iteration:

    document.getElementById(&quot;product_photo_1&quot;).addEventListener(&quot;change&quot;, (event) =&gt; {
for(var index = 1; index &lt;= document.getElementById(&quot;product_photo_1&quot;).files.length; index++) {
uploadImage(event, 1); //passing only the event and an index
}
});
document.getElementById(&quot;product_photo_2&quot;).addEventListener(&quot;change&quot;, (event) =&gt; {
for(var index = 1; index &lt;= document.getElementById(&quot;product_photo_2&quot;).files.length; index++) {
uploadImage(event, 2); //passing only the event and the index
}
});
And now, let&#39;s use `index` for all calls as well as clearing up when it&#39;s 0:
const uploadImage = async (event, id, index) =&gt; {
let context = document.getElementById(&quot;product_photo_&quot; + id + &quot;_result&quot;);
const file = event.target.files[index]; //we get the correct file;
const base64 = await convertBase64(file);
let template = &#39;&lt;img src=&quot;&#39; + base64 + &#39;&quot; class=&quot;img-thumbnail m-2&quot; id=&quot;product_photo_&#39; + id + &#39;[]&quot; style=&quot;height: 50px;&quot; /&gt;&#39;;
if (index === 0) context.innerHTML = template; //clearing older values and adding the first element
else context.innerHTML += template; //appending the (not first) element
};

Instead, you will need to pass the index as well, like this:

    document.getElementById(&quot;product_photo_1&quot;).addEventListener(&quot;change&quot;, (event) =&gt; {
for(var index = 0; index &lt; document.getElementById(&quot;product_photo_1&quot;).files.length; index++) {
uploadImage(event, 1, index);
}
});
document.getElementById(&quot;product_photo_2&quot;).addEventListener(&quot;change&quot;, (event) =&gt; {
for(var index = 0; index &lt; document.getElementById(&quot;product_photo_2&quot;).files.length; index++) {
uploadImage(event, 2, index);
}
});

huangapple
  • 本文由 发表于 2023年5月10日 21:03:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/76218760.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定