File Input with Drag & Drop
File input implementation combining traditional upload and drag-drop with unified validation logic.
Unified File Handler
Single handler function processes both input change and drop events with consistent validation.
const input = document.querySelector('input[type="file"]');
const uploadArea = document.getElementById('upload-area');
const img = document.querySelector('img');
input.addEventListener('change', (e) => {
changeHandler({
e,
callback: (image) => {
console.dir(image, { depth: null });
img.src = image.src;
},
});
});
uploadArea.addEventListener("dragenter", (e) => {
e.preventDefault();
});
uploadArea.addEventListener("dragover", (e) => {
e.preventDefault();
});
uploadArea.addEventListener("dragleave", (e) => {
e.preventDefault();
});
uploadArea.addEventListener("drop", (e) => {
e.preventDefault();
changeHandler({
e,
data: e.dataTransfer.files[0],
callback: (image) => {
console.dir(image, { depth: null });
img.src = image.src;
},
});
});
const changeHandler = ({ e, data, callback }) => {
// drag and dropの場合は e.dataTransfer.files[0] を使用
let file = data === undefined ? e.target.files[0] : data;
// 拡張子チェック
if (!file.type.match(/^image\/(png|jpg|jpeg|gif)$/)) {
return;
}
// 容量チェック(10MB)
if (10 * 1024 * 1024 <= file.size) {
return;
}
let image = new Image();
let fileReader = new FileReader();
fileReader.onload = (e) => {
let base64 = e.target.result;
image.onload = () => {
callback(image);
};
image.src = base64;
};
fileReader.readAsDataURL(file);
};
Key implementation details:
- Extracts file from either
e.target.files
ore.dataTransfer.files
- Validates MIME type against image formats
- Enforces 10MB file size limit
- Converts to base64 using FileReader for preview display