質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
ドラッグ&ドロップ

コンピューターのGUIにおいて、バーチャルなものを「つかむ」ことによって選択し、別の場所や他のバーチャルなものの上に動かす行為、またはその行為に対応していることを指す。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

191閲覧

ドラック&ドロップされたファイルをFileSystemFileHandle型にして、配列で保持したい

dotQ

総合スコア7

ドラッグ&ドロップ

コンピューターのGUIにおいて、バーチャルなものを「つかむ」ことによって選択し、別の場所や他のバーチャルなものの上に動かす行為、またはその行為に対応していることを指す。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2024/03/29 00:14

編集2024/03/29 03:01

実現したいこと

Javascriptでドラックアンドドロップでファイルとフォルダーを操作するアプリを目指して実装しています。

ドロップされたファイルをFile System APIを使い後々保存処理につなげたいです。
※今回は保存処理は問題ではないです。
保存の前処理としてドロップされたファイルのFileSystemFileHandle型を配列で保持しようとしています。

発生している問題・分からないこと

複数ファイルがドロップされたら、event.dataTransfer.itemsでファイル情報を得るためのループを回します。
FileSystemFileHandle型へ変換する

javascript

1const handle = await promiseHandler.getAsFileSystemHandle()

の実行以降(arrayAfter)と以前(arrayBefore)ではpushの挙動が微妙に違うのが何故だかわからないです。
arrayBefore → 想定通り値が入っている。
handles → やりたいこと、配列が入っているようで[0]で参照できないので実態は入っていない。コンソールだと▼で展開すると値が入っているように見える。
arrayAfter → handlesと同じで配列の中身がない、arrayBeforeと同じになってもいいと思うがならない

イメージ説明
不明点
コンソールだと▼で展開すると値が入っていて実際は参照できない状態がよくわからないです。全部解決までいかなくてもそれだけでも教えていただけると助かります。 →ご回答いただきました。

やりたいこと

  • getAsFileSystemHandle()実行後もちゃんとpushで値が入ってくれるようにしたいです。

下記のコードと同じですが動作サンプルです。

該当のソースコード

javascript

1document.addEventListener('DOMContentLoaded', () => { 2 const dropArea = document.getElementById('drop-area') 3 4 dropArea.addEventListener('dragover', (event) => { 5 event.preventDefault(); 6 }); 7 8 dropArea.addEventListener('drop', async (event) => { 9 const handles = [] 10 const arrayBefore = [] 11 const arrayAfter = [] 12 13 event.preventDefault(); 14 const promiseHandlers = [...event.dataTransfer.items] 15 promiseHandlers.forEach(async (promiseHandler) => { 16//前でpushする 17 for (let i = 0; i < 2; i++) { 18 arrayBefore.push(i); 19 } 20 const handle = await promiseHandler.getAsFileSystemHandle() 21 handles.push(handle) 22//後でpushする 23 for (let i = 0; i < 2; i++) { 24 arrayAfter.push(i); 25 } 26 }) 27 console.log('arrayBefore',arrayBefore); 28 console.log('arrayBefore[0]',arrayBefore[0]);// [0] 29 console.log('handles',handles); 30 console.log('handles[0]',handles[0]);// undefined 31 console.log('arrayAfter',arrayAfter); 32 console.log('arrayAfter[0]',arrayAfter[0]); // undefined 33 }); 34}); 35

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

promiseHandlers.forEachをforEachではなく、mapで回して返すようにしたらうまくいきましたが、
だんだん他の処理も入れたり複雑になってしまったのでpushでもできるようになって欲しいです。

補足

MDNのgetAsFileSystemHandle例のコード

javascript

1// すべてのアイテムを処理する 2 for (const item of e.dataTransfer.items) {

上記だと複数ファイルのとき一つのファイルしか取れないので配列に変換してループしています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

forEach() は非同期処理を待ったりしないので、そのあとの console.log()getAsFileSystemHandle() が完了する前に実行されます。ループ中の非同期処理を全て完了するまで待つには、Promise.all() が便利です。

js

1const handles = await Promise.all(promiseHandlers.map( 2 promiseHandler => promiseHandler.getAsFileSystemHandle()));

▼で展開すると値が入っていて実際は参照できない状態

コンソールでオブジェクトを▼で展開した場合、展開された時点での値が表示されます。console.log() 実行時の値ではありません。

投稿2024/03/29 00:32

int32_t

総合スコア20916

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dotQ

2024/03/29 02:53

早めの回答大変助かります。ありがとうございます。 >forEach() は非同期処理を待ったりしない そうだったのですね。ありがとうございます。 for文なら待ちますか? コードもありがとうございます。一行で書けていてとても素敵です。 >コンソールでオブジェクトを▼で展開した場合、展開された時点での値が表示されます。console.log() 実行時の値ではありません。 console.log()実行時はawait待ちで実行されていないから空で、実際に▼をクリックした時点だと全て処理が終わっているので値が入っているということですね。 一番困惑した部分なのでとてもスッキリしました。 ありがとうございます。
int32_t

2024/03/29 03:24

> for文なら待ちますか? はい、for なら問題ないと思います。 元のコードでは forEach() に async 関数を指定していますが、その async を受ける await がないことで逐次実行にならないわけです。for なら async 関数を作る必要がないので、問題はおきませんね。
dotQ

2024/03/29 05:23

引き続きご回答誠にありがとうございます。 なるほどです。何個か試してできそうな気がしてきました。 問題点が明確になり、実装ができるような気がしてきたのでベストアンサーをつけます。 ご丁寧にありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問