一度、アップロードしたファイルについて、サムネイルを表示して、これをユーザーが削除し、
再びアッップロードできるコードをJSで書いております。
removeで削除し、replaceWithで要素を書き換えることができるのですが、改めてfileをアップロードするとサムネイルが表示されなくなってしまいます。
どの点に問題があるか解決ができなかったため質問させていただきます。
宜しくお願い申し上げます。
<!DOCTYPE html>
<html>
<head>
<title>XXX</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
</head>
<body>
<section>
<form class="" action="Z_confirm.php" method="post" enctype="multipart/form-data">
<div class="fileUpload">
<div id="drop_zone">
<p style="font-size: 12px;">ここにファイルをドロップ</p>
<p style="font-size: 10px;">または</p>
<label for="files" class="fileupImg"><i class="plus icon"></i>ファイルを選択
<input type="file" id="files" style="display: none" value="2097152" name="file" multiple />
</label>
</div>
<figure>
<output id="list"></output>
</figure>
<div class="fileInfo"></div>
</div>
<script>
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
// Loop through the FileList and render image files as thumbnails.
for (var i = 0, f; f = files[i]; i++) {
// Only process image files.
if (!f.type.match('image.*')) {
continue;
}
var reader = new FileReader();
// Closure to capture the file information.
reader.onload = (function(theFile) {
return function(e) {
// Render thumbnail.
var span = document.createElement('span');
span.innerHTML = ['<img class="thumbnail" src="', e.target.result,
'" title="', escape(theFile.name), '"/>'].join('');
document.getElementById('list').insertBefore(span, null);
};
})(f);
// Read in the image file as a data URL.
reader.readAsDataURL(f);
}
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>
<script>
function handleDragOver(evt) {
evt.stopPropagation();
evt.preventDefault();
evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
}
// Setup the dnd listeners.
var dropZone = document.getElementById('drop_zone');
dropZone.addEventListener('dragover', handleDragOver, false);
dropZone.addEventListener('drop', handleFileSelect, false);
dropZone.ondrop = function(e) {
e.preventDefault();
this.className = 'dropzone';
console.log(e.dataTransfer.files);
var fileInput = document.getElementById('files'); //fileのinputタグ取得
var file = e.dataTransfer.files; //アップロード対象ファイル情報取得
fileInput.files = file; //fileのinputタグへセット
};
</script>
<button type="button" name="button" id="delete" style="height:20px;">X</button>
<input class="submit step-button" type="submit" value="登録する">
</form>
</section>
<script src="assets/js/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
$('#sidebar>a').css('color','#555555');
});
</script>
<script type="text/javascript">
$(function(){
$('#delete').on('click',function(){
$('#files').replaceWith($('#files').clone());
$('#list').find('span').remove();
})
})
</script>
</body>
</html>
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+1
当方、生のJavascriptを書いたことがなくコードが理解できなかったのでJqueryのみで書いてみました。書いているうちに少し大きめになってしまいました。すみません。参考にしていただけますと幸いです。
[コード書き直しました]
ものすごく勘違いしてましたしっかり確認せずすみません。
問題は、ブラウザがfileをキャッシュするためchangeイベントが発生しないのが問題のようです。
コードを一部書き換えました勘違いしてましたすみません。
ポイントはこちらです。valueを削除しています。
el.input.prop('value','');
生のjavascriptならクリックイベントで
this.value = null;
でいけそうです。(未検証)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<form action="Z_confirm.php" method="post" enctype="multipart/form-data">
<label for="files" class="fileupImg"><i class="plus icon"></i>ファイルを選択
<input type="file" id="files" style="display: none" value="2097152" name="file" multiple />
</label>
</div>
<figure>
<output id="list"></output>
</figure>
<div class="fileInfo"></div>
<button type="button" name="button" id="delete" style="height:20px;">X</button>
<br>
<br>
<input class="submit step-button" type="submit" value="登録する">
</form>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script type="text/javascript">
jQuery(function()
{
// セットアップ
var obj = form.fileSelect({
input : '#files',
list : '#list',
deleteBtn : '#delete',
thumbnail : { width : 150, class : 'thumbnail' },
//複数のファイルを許可するか?
multipleFile : true
});
// ファイルをセットした時に発火するイベント 引数に選択したファイルが返ってくる
obj.OnSelectFile(function(file)
{
console.log(file);
//ファイルが存在するか?
console.log(obj.hasFile());
//すべてのファイルを取得 配列
console.log(obj.getFiles());
});
//すべてのファイルをリセット
obj.reset();
});
</script>
<script>
var form;
(function(g,$)
{
g.fileSelect = function(setting)
{
var el = {}, data = {};
var init = function()
{
el.input = $(setting.input);
el.list = $(setting.list);
el.deleteBtn = $(setting.deleteBtn);
data.files = [];
setUp();
};
var setUp = function()
{
el.input.on('change', handleFileSelect);
el.deleteBtn.on('click', deleteFile);
};
var hasFile = function() { return data.files.length > 0; }
var getFiles = function() { return data.files; };
var handleFileSelect = function(e)
{
var file = e.target.files[0],
reader = new FileReader();
if(file.type.indexOf("image") < 0) return false;
reader.onload = (function(file)
{
return function(e)
{
if(!setting.multipleFile) reset();
file.src = e.target.result;
data.files.push(file);
var spn = $('<span>');
spn.append($('<img>').attr({
src: file.src,
width: setting.thumbnail.width,
class: setting.thumbnail.class,
title: file.name
}));
el.list.append(spn);
el.input.trigger( "OnSelectFile", file );
reader.va
};
})(file);
reader.readAsDataURL(file);
};
var deleteVal = function()
{
el.input.prop('value','');
};
var deleteFile = function()
{
el.list.html('');
data.files = [];
deleteVal();
};
var OnSelectFile = function(fn)
{
el.input.on('OnSelectFile', function(e, f){
fn(f);
});
}
var reset = function(){
data.files = [];
el.list.html('');
deleteVal();
};
init();
return {
OnSelectFile : OnSelectFile,
hasFile : hasFile,
getFiles : getFiles,
reset : reset
}
};
}(form || (form = {}), jQuery));
</script>
</body>
</html>
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+1
要素を差し替えていることによって、イベントリスナの設定が壊れているのだと思います。
対策としては、要素を差し替えない方式(たとえばdetachメソッドはイベントを壊しません)に切り替えるか、バブリングを拾う(参考)か、だと思います。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.11%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
m.ts10806
2017/08/17 09:18
ブラウザの開発ツールで確認しますと幾つかエラーがはかれているようですが、そちらは本件とは関係ないでしょうか?
m.ts10806
2017/08/17 09:37
htmlが2つあるようですが、2ファイルあるのであればcodeをわけてください。
pegy
2017/08/17 11:02
コメント有難うございます。ファイルは誤って重複して記載してしまいました。大変失礼致しました、修正削除いたしました。また、エラー自体は簡略化するために生じているもので、本体とは関係がないとお考えください。jsbinのconsoleも同様です。
kei344
2017/08/17 11:07
関数handleFileSelectが2つあるなど、「簡略化」の仕方に問題があるのでは。ひとまずエラーが出ずに状況が再現できるコードを提示されてはいかがでしょうか。
pegy
2017/08/17 12:39
コメントありがとうございます。簡略化をせずにエラーのないコードに修正を致しました。