需求:`input[multiple]` 選圖 → 即時預覽縮略圖 → 每圖下方輸入描述 → 提交時圖片+描述配對上傳。
function previewImages(input) {
const files = input.files;
const preview = document.getElementById('preview');
preview.innerHTML = '';
for (let i = 0; i < files.length; i++) {
const file = files[i];
if (!file.type.startsWith('image/')) continue;
const wrapper = document.createElement('div');
wrapper.className = 'img-wrapper';
wrapper.dataset.index = i;
const img = document.createElement('img');
img.src = URL.createObjectURL(file);
img.onload = () => URL.revokeObjectURL(img.src);
const desc = document.createElement('textarea');
desc.placeholder = '輸入描述...';
desc.dataset.index = i;
wrapper.appendChild(img);
wrapper.appendChild(desc);
preview.appendChild(wrapper);
}
}
// 提交時收集
function collectData() {
const formData = new FormData();
const files = document.getElementById('myimage').files;
const descs = document.querySelectorAll('#preview textarea');
descs.forEach(ta => {
const idx = +ta.dataset.index;
if (idx < files.length) {
formData.append('files', files[idx]);
formData.append(`desc_${idx}`, ta.value);
}
});
return formData; // fetch/post 發送
}
<input type="file" id="myimage" multiple accept="image/*" onchange="previewImages(this)" />
<div id="preview" style="display:flex; flex-wrap:wrap; gap:10px;"></div>
<button onclick="submitData()">提交</button>
按 `files` 陣列與 `desc_0`、`desc_1`... 配對入庫,或前端壓縮為 JSON 字段 `images: [{file, desc}]`。