File Input with Drag & Drop

Preview

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 or e.dataTransfer.files
  • Validates MIME type against image formats
  • Enforces 10MB file size limit
  • Converts to base64 using FileReader for preview display