0
0

ドラッグアンドドロップでファイルをアップロードができ、画像の場合はプレビューも見れるJS

Last updated at Posted at 2024-07-09
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>ドラッグアンドドロップでファイルアップロード</title>
    <style></style>
  </head>
  <body>
    <style>
      .js-fileUpload {
        border: 1px dashed #9b9b9b;
        border-radius: 10px;
        padding: 42px;
        text-align: center;
      }

      .text {
        margin-bottom: 10px;
      }

      .file-name {
        margin-top: 10px;
      }

      .is-hidden {
        display: none !important;
      }

      .file-preview {
        display: flex;
        justify-content: center;
        margin: 20px auto 10px;
      }

      .file-preview img {
        max-height: 400px;
        object-fit: contain;
      }

      .upload-button {
        background-color: #333;
        border-radius: 5px;
        color: #fff;
        padding: 5px 10px;
        width: 150px;
      }

      .cancel-button {
        border: 1px solid #333;
        border-radius: 5px;
        margin: 10px auto 0;
        padding: 5px 10px;
        width: 150px;
      }
    </style>
    <div class="js-fileUpload">
      <div class="text">ここにファイルをドラッグ&ドロップ</div>
      <input type="file" class="file-input is-hidden" multiple />
      <button class="upload-button">ファイル選択</button>
      <div class="file-preview is-hidden"></div>
      <div class="file-name is-hidden"></div>
      <div class="cancel-button is-hidden">キャンセル</div>
    </div>
    <script>
      document.addEventListener("DOMContentLoaded", () => {
        const fileUpload = document.querySelector(".js-fileUpload");

        if (fileUpload) {
          const text = fileUpload.querySelector(".text");
          const fileInput = fileUpload.querySelector(".file-input");
          const uploadButton = fileUpload.querySelector(".upload-button");
          const cancelButton = fileUpload.querySelector(".cancel-button");
          const fileName = fileUpload.querySelector(".file-name");
          const preview = fileUpload.querySelector(".file-preview");

          fileUpload.addEventListener("dragover", (event) => {
            event.preventDefault();
            fileUpload.style.borderColor = "#666";
          });

          fileUpload.addEventListener("mouseover", (event) => {
            event.preventDefault();
            fileUpload.style.borderColor = "#666";
          });

          fileUpload.addEventListener("dragleave", (event) => {
            event.preventDefault();
            fileUpload.style.borderColor = "";
          });

          fileUpload.addEventListener("mouseout", (event) => {
            event.preventDefault();
            fileUpload.style.borderColor = "";
          });

          fileUpload.addEventListener("drop", (event) => {
            event.preventDefault();
            fileUpload.style.borderColor = "";
            const files = event.dataTransfer.files;
            if (files.length > 0) {
              // 新しいDataTransferオブジェクトを作成し、ドロップされたファイルを設定
              const dataTransfer = new DataTransfer();
              for (let i = 0; i < files.length; i++) {
                dataTransfer.items.add(files[i]);
              }
              fileInput.files = dataTransfer.files;
              handleFiles(files);
              fileInput.dispatchEvent(new Event("change")); // changeイベントを手動でトリガー
            }
          });

          uploadButton.addEventListener("click", () => {
            if (fileInput.files.length > 0) {
              alert("ファイルをアップロードしました。");
            } else {
              fileInput.click();
            }
          });

          fileInput.addEventListener("change", () => {
            if (fileInput.files.length > 0) {
              handleFiles(fileInput.files);
            }
          });

          cancelButton.addEventListener("click", () => {
            fileInput.value = "";
            fileName.textContent = "";
            preview.innerHTML = "";
            uploadButton.textContent = "ファイル選択";
            text.classList.remove("is-hidden");
            preview.classList.add("is-hidden");
            cancelButton.classList.add("is-hidden");
          });

          function handleFiles(files) {
            if (files.length > 0) {
              fileName.classList.remove("is-hidden");
              fileName.textContent = Array.from(files)
                .map((file) => file.name)
                .join(", ");

              text.classList.add("is-hidden");
              uploadButton.textContent = "選択したファイルをアップロードする";
              preview.innerHTML = "";
              preview.classList.remove("is-hidden");

              Array.from(files).forEach((file) => {
                if (file.type.startsWith("image/")) {
                  const reader = new FileReader();
                  reader.onload = (e) => {
                    const img = document.createElement("img");
                    img.src = e.target.result;
                    preview.appendChild(img);
                  };
                  reader.readAsDataURL(file);
                }
              });
            }
            fileName.classList.add("is-hidden");
            cancelButton.classList.remove("is-hidden");
          }
        }
      });
    </script>
  </body>
</html>


0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0