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

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

ただいまの
回答率

87.34%

[javascript] 画像選択時に定されたFileListオブジェクトから、特定のkeyを消す

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 3,975

score 120

フォームより画像を複数選択して、submit前に画像のプレビューを表示させるコードを書きに書きました。また各画像のプレビューには、削除ボタンをつけて、クリックすればjQueryで、消えるようにしています。また、消えた部分の画像は非表示になっているだけなので、FileListオブジオェクとの中には、まだ残っているので、こちらもクリック時に消したいと思うのですが、FileListオブジェクトのなかから、指定したkeyのデータを削除したいのですが、うまくいきません。どのように書くのがよいでしょうか?

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title></title>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>

<style>
  .thumb {
    height: 75px;
    border: 1px solid #000;
    margin: 10px 5px 0 0;
  }
</style>

<form id='form' action="data.php" method="post" enctype="multipart/form-data">
<input type="file" id="files" name="files[]" multiple />
<button class="show">ボタン</button>
</form>


<output id="list"></output>

<script>

  $('output').on('click','.del',function(){
    var id = $(this).prev().attr('id');
    id = id.split("_");
         id[1];

    //alert(id);
/* この部分がどう書けばFileListから消えるのかがわかりません。
    if(id[1] in FileList) {
    delete FileList[id[1]];
         }
*/
    $(this).parent().replaceWith();
  });



  function handleFileSelect(evt) {
    var files = evt.target.files;

    for (var i = 0, f; f = files[i]; i++) {

      if (!f.type.match('image.*')) {
        continue;
      }

      var reader = new FileReader();

      reader.onload = (function(theFile, num) {
        return function(e) {
          var span = document.createElement('span');
          span.innerHTML = ['<div class="view"><img id ="img_' + num + ' " class="thumb" src="', e.target.result,
                            '" title="', escape(theFile.name), '"/><div class="del">×</div></div>'].join('');
          document.getElementById('list').insertBefore(span, null);
        };
      })(f, i);

      reader.readAsDataURL(f);
    }
      console.log(files);
  }

  document.getElementById('files').addEventListener('change', handleFileSelect, false);



</script>

</body>
</html>
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kei344

    2017/07/22 19:55

    https://teratail.com/questions/85243 こちらの内容と同じでは?新たに質問するのではなくもとの質問を編集されてはいかがでしょう。

    キャンセル

  • xjaPANDA

    2017/07/22 20:58

    ご指摘ありがとうございます。こちらの質問は、画像選択時に、選択するさいに、制限が可能かどうかについてなので、異なります。一方、こちらの質問内容はオブジェクトの中の特定のキーの削除です。https://teratail.com/questions/85243 のほうを違いがわかるように修正いたします。

    キャンセル

回答 1

checkベストアンサー

+3

FileListはreadonlyですので、削除はできないはずです。
そこで逆転の発想です。
通常のフォーム機能では送りたくないファイルを削れないのですから、自前のフォーム機能で送りたいファイルだけを送りましょう。
html5のFormDataは、かなり自由にカスタマイズしたデータを送れます。

var fd = new FormData();
fd.append('hoge','hage');// hogeっていうキーのデータはhageだよ
fd.append('file',files[i]);// アップロードしたいファイルだけをここで追加すればいいわけです
fd.append('str',new Blob(["hoge,moge,mage"]));// なんらかのデータ列ならBlobにしちゃえば、それをファイルってことにして送れます
$.ajax({
    type : 'POST',
    url: "data.php",
    contentType:false,// FormData送信用の設定その1。BlobとFileがサーバのファイルアップロードとして(phpでなら$_FILESとして)処理されます
    processData: false,// FormData送信用の設定その2。 データの暗黙変換が行われなくなります
    data : fd,
    success : function(res){
        console.log(res);
    }
});

jQueryのajax向けの使い方だけをざっと紹介しました。
FormDataをググれば、既存のformタグを乗っ取るような形の使い方などが見つかったりしますので、うまく使いこなしてください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/23 02:10

    readonlyとかあるんですね。知らずに、deleteで踏ん張っていましたので、まったく見当違いでした。とても勉強になります。また、非同期で画像をアップロードできることは知りませんでした。これができると、いろいろ広がりますね。とても便利です。今回 アドバイスいただいたコードを関数の中に組み込み利用しました。かなり便利です。感動です。 また削除については、こちらも非同期で削除するようにしました。制限については、とりあえず、データベースで、ファイル名、補足情報等を管理し、データの個数をかぞえて、制限をかけようと思っています。 

    キャンセル

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

  • ただいまの回答率 87.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る