Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
1
Help us understand the problem. What is going on with this article?
@YutoTakahashi

Edge,IE11だけFileListにevent.dataTransfer.filesが入らない

More than 1 year has passed since last update.

経緯

ドラッグ&ドロップ式 ファイルアップロード画面のIE対応でハマった話
モダンブラウザではきちんと動くのに、edgeとIE11だけドロップしても動かない。

// input要素
const fileInput = document.getElementById("fileInput")
// ファイルをdropする要素
const dropTarget = document.getElementById("dropTarget")

function hoge(event) {
  event.preventDefault()
  event.stopPropagation()
  event.dataTransfer.dropEffect = 'copy'
}

function fuga(event) {
  event.stopPropagation()
  event.preventDefault()
  fileInput.files = event.dataTransfer.files; //今回問題の部分
}

dropTarget.addEventListener('dragover', e => {
  hoge(e)
})
dropTarget.addEventListener('drop', e => {
  fuga(e)
})

よくあるドラッグ&ドロップでフォーム実装する時の処理ですね。
<input type="file">のFileListオブジェクトに対して、
なぜかIE系だけevent.dataTransfer.filesが入らない。
これに結構ハマりました。

対応

何やらIEからは「厳密モードのFileListは読み取り専用なので代入できません」って怒られます。
babelが吐き出してくれるソースにはデフォルトでuse strictが付くので、取っちゃおうかと考えました。

.babelrc
{
  "sourceType": "script"
}

"sourceType": "script".babelrcに追加することで、
バベられた後のソースからuse strictを取っ払うことができます。

しかしこの対応でも動かない。

しかも"sourceType": "script"を指定すると
import/exportがつかえなくなります。(しんどい)
何よりuse strictを取るって対応そのものが単純に敗北感が強い。

解決

色々調べましたが、結局あまりスマートな解決の糸口が見つからず、
event.dataTransfer.files<input type="file">
FileListオブジェクトに突っ込まない方法で解決。


// input要素
const fileInput = document.getElementById("fileInput")
// 画像をdropする要素
const dropTarget = document.getElementById("dropTarget")

function piyo(data) {
  const formData = new FormData(document.getElementById("form"))
  formData.append('image', fileData[0])
  //APIコール用のロジック
}

function hoge(event) {
  event.preventDefault()
  event.stopPropagation()
  event.dataTransfer.dropEffect = 'copy'
}

function fuga(event) {
  event.stopPropagation()
  event.preventDefault()
  piyo(event.dataTransfer.files);
}

dropTarget.addEventListener('dragover', e => {
  hoge(e)
})
dropTarget.addEventListener('drop', e => {
  fuga(e)
})

event.dataTransfer.filesを引数で渡していって
formdataに突っ込んでAPIに投げてあげる形に。
formdataがFilelistオブジェクトしか受け付けない。
みたいになってたら詰んでました。

File()で新しくインスタンス生成する方向でも考えたものの、
第二引数に渡すBlob型のデータをdropで取得する方法がわからないのと、
普通にクリック処理でファイルを受け取る場合は
<input type="file">のデフォルトの挙動に頼っていたので断念。

これ上手なやり方ご存知の方はぜひ教えてください。

1
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
YutoTakahashi
直感型フロントエンドエンジニア

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
1
Help us understand the problem. What is going on with this article?