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

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

新規登録して質問してみよう
ただいま回答率
85.50%
JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

2回答

5117閲覧

replaceWithでcloneしたinput type="file" 要素で再度、アップロードできない

pegy

総合スコア243

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

0クリップ

投稿2017/08/16 23:41

編集2017/08/17 03:38

一度、アップロードしたファイルについて、サムネイルを表示して、これをユーザーが削除し、
再びアッップロードできるコードをJSで書いております。

JSBIN

removeで削除し、replaceWithで要素を書き換えることができるのですが、改めてfileをアップロードするとサムネイルが表示されなくなってしまいます。
どの点に問題があるか解決ができなかったため質問させていただきます。
宜しくお願い申し上げます。

HTML

1<!DOCTYPE html> 2<html> 3 <head> 4 <title>XXX</title> 5 <meta charset="utf-8" /> 6 <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" /> 7 8 <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"> 9<script src="https://code.jquery.com/jquery-3.1.0.js"></script> 10 11 12 13 </head> 14 <body> 15 16 17<section> 18 <form class="" action="Z_confirm.php" method="post" enctype="multipart/form-data"> 19 20 <div class="fileUpload"> 21 <div id="drop_zone"> 22 <p style="font-size: 12px;">ここにファイルをドロップ</p> 23 <p style="font-size: 10px;">または</p> 24 <label for="files" class="fileupImg"><i class="plus icon"></i>ファイルを選択 25 <input type="file" id="files" style="display: none" value="2097152" name="file" multiple /> 26 </label> 27 </div> 28 <figure> 29 <output id="list"></output> 30 </figure> 31 <div class="fileInfo"></div> 32 </div> 33 34 <script> 35function handleFileSelect(evt) { 36var files = evt.target.files; // FileList object 37 38// Loop through the FileList and render image files as thumbnails. 39for (var i = 0, f; f = files[i]; i++) { 40 41// Only process image files. 42if (!f.type.match('image.*')) { 43continue; 44} 45var reader = new FileReader(); 46 47// Closure to capture the file information. 48reader.onload = (function(theFile) { 49return function(e) { 50// Render thumbnail. 51var span = document.createElement('span'); 52span.innerHTML = ['<img class="thumbnail" src="', e.target.result, 53'" title="', escape(theFile.name), '"/>'].join(''); 54document.getElementById('list').insertBefore(span, null); 55}; 56})(f); 57// Read in the image file as a data URL. 58reader.readAsDataURL(f); 59} 60} 61document.getElementById('files').addEventListener('change', handleFileSelect, false); 62</script> 63 64 <script> 65 function handleDragOver(evt) { 66 evt.stopPropagation(); 67 evt.preventDefault(); 68 evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy. 69 } 70 71 // Setup the dnd listeners. 72 var dropZone = document.getElementById('drop_zone'); 73 dropZone.addEventListener('dragover', handleDragOver, false); 74 dropZone.addEventListener('drop', handleFileSelect, false); 75 76 dropZone.ondrop = function(e) { 77 e.preventDefault(); 78 this.className = 'dropzone'; 79 console.log(e.dataTransfer.files); 80 var fileInput = document.getElementById('files'); //fileのinputタグ取得 81 var file = e.dataTransfer.files; //アップロード対象ファイル情報取得 82 fileInput.files = file; //fileのinputタグへセット 83 }; 84 85 </script> 86<button type="button" name="button" id="delete" style="height:20px;">X</button> 87<input class="submit step-button" type="submit" value="登録する"> 88</form> 89 90</section> 91 92 <script src="assets/js/jquery.min.js"></script> 93 <script type="text/javascript"> 94 $(function(){ 95 $('#sidebar>a').css('color','#555555'); 96 }); 97 </script> 98 99 <script type="text/javascript"> 100 $(function(){ 101 $('#delete').on('click',function(){ 102 $('#files').replaceWith($('#files').clone()); 103 $('#list').find('span').remove(); 104 }) 105 }) 106 </script> 107 108 </body> 109</html> 110 111 112

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

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

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

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

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

m.ts10806

2017/08/17 00:18

ブラウザの開発ツールで確認しますと幾つかエラーがはかれているようですが、そちらは本件とは関係ないでしょうか?
m.ts10806

2017/08/17 00:37

htmlが2つあるようですが、2ファイルあるのであればcodeをわけてください。
pegy

2017/08/17 02:02

コメント有難うございます。ファイルは誤って重複して記載してしまいました。大変失礼致しました、修正削除いたしました。また、エラー自体は簡略化するために生じているもので、本体とは関係がないとお考えください。jsbinのconsoleも同様です。
kei344

2017/08/17 02:07

関数handleFileSelectが2つあるなど、「簡略化」の仕方に問題があるのでは。ひとまずエラーが出ずに状況が再現できるコードを提示されてはいかがでしょうか。
pegy

2017/08/17 03:39

コメントありがとうございます。簡略化をせずにエラーのないコードに修正を致しました。
guest

回答2

0

ベストアンサー

当方、生のJavascriptを書いたことがなくコードが理解できなかったのでJqueryのみで書いてみました。書いているうちに少し大きめになってしまいました。すみません。参考にしていただけますと幸いです。

[コード書き直しました]
ものすごく勘違いしてましたしっかり確認せずすみません。
問題は、ブラウザがfileをキャッシュするためchangeイベントが発生しないのが問題のようです。
コードを一部書き換えました勘違いしてましたすみません。

参考ページ

ポイントはこちらです。valueを削除しています。

javascript

1el.input.prop('value','');

生のjavascriptならクリックイベントで

javascript

1this.value = null;

でいけそうです。(未検証)

javascript

1<!DOCTYPE html> 2<html> 3<head> 4 <meta charset="utf-8"> 5 <meta name="viewport" content="width=device-width"> 6 <title>JS Bin</title> 7 </head> 8<body> 9 <form action="Z_confirm.php" method="post" enctype="multipart/form-data"> 10 11 <label for="files" class="fileupImg"><i class="plus icon"></i>ファイルを選択 12 <input type="file" id="files" style="display: none" value="2097152" name="file" multiple /> 13</label> 14 </div> 15 <figure> 16 <output id="list"></output> 17 </figure> 18 <div class="fileInfo"></div> 19 20 <button type="button" name="button" id="delete" style="height:20px;">X</button> 21<br> 22<br> 23 <input class="submit step-button" type="submit" value="登録する"> 24</form> 25 26 27 <script src="https://code.jquery.com/jquery-3.1.0.js"></script> 28 <script type="text/javascript"> 29 jQuery(function() 30 { 31 // セットアップ 32 var obj = form.fileSelect({ 33 input : '#files', 34 list : '#list', 35 deleteBtn : '#delete', 36 thumbnail : { width : 150, class : 'thumbnail' }, 37 //複数のファイルを許可するか? 38 multipleFile : true 39 }); 40 41 // ファイルをセットした時に発火するイベント 引数に選択したファイルが返ってくる 42 obj.OnSelectFile(function(file) 43 { 44 console.log(file); 45 46 //ファイルが存在するか? 47 console.log(obj.hasFile()); 48 49 //すべてのファイルを取得 配列 50 console.log(obj.getFiles()); 51 }); 52 53 //すべてのファイルをリセット 54 obj.reset(); 55 56 }); 57 </script> 58 59 <script> 60 var form; 61 (function(g,$) 62 { 63 g.fileSelect = function(setting) 64 { 65 var el = {}, data = {}; 66 67 var init = function() 68 { 69 el.input = $(setting.input); 70 el.list = $(setting.list); 71 el.deleteBtn = $(setting.deleteBtn); 72 73 data.files = []; 74 75 setUp(); 76 }; 77 78 var setUp = function() 79 { 80 el.input.on('change', handleFileSelect); 81 el.deleteBtn.on('click', deleteFile); 82 }; 83 84 var hasFile = function() { return data.files.length > 0; } 85 var getFiles = function() { return data.files; }; 86 87 var handleFileSelect = function(e) 88 { 89 var file = e.target.files[0], 90 reader = new FileReader(); 91 92 if(file.type.indexOf("image") < 0) return false; 93 94 reader.onload = (function(file) 95 { 96 return function(e) 97 { 98 if(!setting.multipleFile) reset(); 99 100 file.src = e.target.result; 101 data.files.push(file); 102 var spn = $('<span>'); 103 spn.append($('<img>').attr({ 104 src: file.src, 105 width: setting.thumbnail.width, 106 class: setting.thumbnail.class, 107 title: file.name 108 })); 109 110 el.list.append(spn); 111 112 el.input.trigger( "OnSelectFile", file ); 113 114 reader.va 115 }; 116 })(file); 117 118 reader.readAsDataURL(file); 119 }; 120 121 var deleteVal = function() 122 { 123 el.input.prop('value',''); 124 }; 125 126 var deleteFile = function() 127 { 128 el.list.html(''); 129 data.files = []; 130 deleteVal(); 131 }; 132 133 var OnSelectFile = function(fn) 134 { 135 el.input.on('OnSelectFile', function(e, f){ 136 fn(f); 137 }); 138 } 139 140 var reset = function(){ 141 data.files = []; 142 el.list.html(''); 143 deleteVal(); 144 }; 145 146 init(); 147 148 return { 149 OnSelectFile : OnSelectFile, 150 hasFile : hasFile, 151 getFiles : getFiles, 152 reset : reset 153 } 154 }; 155 }(form || (form = {}), jQuery)); 156 </script> 157</body> 158</html>

投稿2017/08/17 04:19

編集2017/08/17 05:35
IShix

総合スコア1724

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

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

pegy

2017/08/17 04:43

ご回答ありがとうございます。また、細かいコードまでご提示頂き、御礼申し上げます。 早速動かしてみたのですが、Aファイルをアップして、削除後にBファイルをアップする場合には機能するのですが、Aファイルをアップして、削除後に再びAファイルをアップすること(厳密にはサムネイルに表示すること)ができません。これはdeleteFileでも削除ができておらずコンフリクトしている等の原因によるものでしょうか、、もしアドバイスを頂けるとうれしいです。 宜しくお願い申し上げます。
IShix

2017/08/17 05:40

僕が勘違いしていたようです。申し訳ありません。 コードを修正しましたのでご確認ください。 よろしくお願いいたします。
pegy

2017/08/17 07:38

IShikawan様 とんでもないです、ご親切にご教示を頂き有難うございます。 一旦ブラウザにfileがcashされると、新たにchangeイベントが起きても動作をしてくれないのですね。。 Jqueryのコードにつきましては正しく動作いたしました! 初心者で申し訳なく、最後に教えて頂きたいのですが cashしたファイルをvalue属性を削除することで、なぜクリアすることができるのでしょうか? inputを要素毎削除するのにvalueを個別に削除する点が調べても分かりませんでした。。 また、this.value=null;の場合、input要素のvalue要素を削除したいということであればthisはinputエレメントを指しているとして.valueのこのプロパティは何を指しているのでしょうか。。。?
guest

0

要素を差し替えていることによって、イベントリスナの設定が壊れているのだと思います。
対策としては、要素を差し替えない方式(たとえばdetachメソッドはイベントを壊しません)に切り替えるか、バブリングを拾う(参考)か、だと思います。

投稿2017/08/17 04:18

Lhankor_Mhy

総合スコア35865

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

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

pegy

2017/08/17 04:48

コメント頂き有難うございます。原因については、ずっと考えていたため、ご教示頂きありがとうございます。removeさせずに、detachメソッドでは今のところうまく機能しなかったのですが、ハブリングを拾う方法も試した見ようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問