###前提
画像をアップロードするとプレビュー画像が表示されます。
そしてプレビュー画像と連動して、inputに画像データが入る仕組みになっています。
4つプレビュー画像が表示される仕組みで、それぞれidが0-3まで振られております。
例えば2番目の画像(idがupload-form-1)を削除すると、upload-form-2はupload-form-1に変化する仕組みになっています。
###実現したい事
プレビュー画像を消した際に、inputに入っている画像データを削除したいです。
1つ目の削除は成功しますが、2つ目以降の削除はできない状況です。
upload-form-1を削除した後、upload-form-2がupload-form-1に変化し、そのupload-form-1を削除しようとするとできない状況です。
エラー文 product_image_upload.self-dba68cdfccdaaa5a7b0f47bb03e77ba367404159be91200b746990224297fc9b.js?body=1:131 Uncaught TypeError: Cannot read property 'remove' of null at HTMLAnchorElement.<anonymous> (product_image_upload.self-dba68cdfccdaaa5a7b0f47bb03e77ba367404159be91200b746990224297fc9b.js?body=1:131) at HTMLDocument.dispatch (jquery.self-bd7ddd393353a8d2480a622e80342adf488fb6006d667e8b42e4c0073393abee.js?body=1:5227) at HTMLDocument.elemData.handle (jquery.self-bd7ddd393353a8d2480a622e80342adf488fb6006d667e8b42e4c0073393abee.js?body=1:4879)
###原因
ドラッグアンドドロップした際に、画像データをinputに引き渡す仕組みで実装しております。
js
1// 指定部分に画像をドロップした際の処理 2 droparea.addEventListener('drop', function (e) { 3 e.stopPropagation(); 4 // ドロップ時にファイルが開かないようにする 5 e.preventDefault(); 6 // アップロードされた画像ファイルデータの取得 7 var uploaded_file_data = e.dataTransfer.files; 8 9 // 1番目にドロップさたものは1番目のinputタグに、2番目は2番目のinputタグにといったようにのD&Dされた画像データをinputタグに入れ込むために、プレビュー画像のliタグのidと連動させる。 10 var preview_count = PreviewCount(); 11 12 // D&Dのデータを指定のinputタグに入れ込む(生成されているinputタグの個数をidに組み込むことで、ドロップとinputへの入れ込みを連動させる) 13 document.getElementById('upload-form-' + preview_count).files = uploaded_file_data 14 15 // プレビューを表示するための画像データを取得 16 const reader = new FileReader(); 17 reader.readAsDataURL(e.dataTransfer.files[0]); 18 reader.onload = function (e) { 19 var upload_image = e.target.result 20 // プレビュー表示の関数を呼び出す 21 appendImage(upload_image); 22 ImageCount(); 23 PreviewCount(); 24 } 25 }); 26 27 // inputタグにデータが入る毎に新しいinputフォームを作成する 28 $("#drop").change(function(e) { 29 var upload_form = $("#drop") 30 31 // プレビュー画像と連動し、idが変わったinputタグを生成するため、初期値0のPreviewCountに+1したものを変数に定義しidに組み込む 32 var preview_count = PreviewCount() + 1; 33 34 // inputタグが4つになったら追加を止める、すなわちi_countが4以上になったら追加を止める条件式。 35 if (preview_count <= 4){ 36 var input_form = `<input class='product_images' id='upload-form-${preview_count}' multiple='multiple' name='images[image][]' type='file'>` 37 // inputタグに画像データが投入されたら、新たなinputタグを生成する 38 upload_form.append(input_form); 39 } 40 }); 41 42 43 // D&Dされた画像のプレビューを表示 44 function appendImage(upload_image){ 45 // var i_count = ImageCount() + 1; 46 var upload_area = $(".sell-dropbox-items ul"); 47 var html = `<li class='sell-dropbox-items_container'> 48 <div class='sell-dropbox-items-figure'> 49 <img alt='商品画像' src='${upload_image}'> 50 </div> 51 <a class="sell-dropbox-items-btn sell-image_edit"> 52 <p>編集</p> 53 </a> 54 <a class="sell-dropbox-items-btn sell-image_delete"> 55 <p>削除</p> 56 </a> 57 </li>` 58 upload_area.append(html); 59 }
そして削除機能は以下のように実装しております。
js
1 // 削除機能 2 $(document).on("click",".sell-image_delete",function(e) { 3 $(this).parent().remove(); 4 var delete_obj = this.parentNode; 5 var delete_obj_id = delete_obj.id; 6 var delete_input_data = document.getElementById('upload-form-' + delete_obj_id); 7 delete_input_data.remove(); 8 ImageCount(); 9 PreviewCount(); 10 InputCount(); 11 12 }); 13 14コード
おそらく原因は以下でないかと考えております。
// アップロードされた画像ファイルデータの取得
var uploaded_file_data = e.dataTransfer.files;
によってinputにデータを受け渡している。→削除するとinputのidが変わる。→しかしアップロードした際に引き渡したinputのidは削除前のものに引き渡されている。
jsでidの変更は行われているが、画像データの引き渡しとは連動していない。
具体的には、
ドラッグアンドドロップをする→inputのidがupload-form-2のものに画像ファイルが引き渡される。
upload-form-1のプレビューを削除→input(idがupload-form-1)のデータが削除され、upload-form-2がupload-form-1に変化する。
そのupload-form-1を削除する、しかし画像データはupload-form-2のものに引き渡したため、画像データがない(以下のエラー文が発生する)=削除イベントが実行されない。(javascriptは一度htmlを読み込んだ後に実行されるため、見た目でidは変化しているが、htmlは再度読み込まれていないため)
Uncaught TypeError: Cannot read property 'remove' of null
###対策として考えた事
削除イベント実施後、ページを再度リロードしてDOMの読み込みを実施すればいけるかも?と思いましたが、それを行うとアップロードした画像が全てリセットされてしまいました。(当たり前でした・・・)
###教えていただきたい事
イメージはメルカリの商品出品時の画像アップロード機能です。
アップロードされた画像を消した際に、新たなidが付与され、その新たなidが付与されたものも削除したい場合どのように実装すれば良いでしょうか?