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

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

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

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

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

jQuery

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

Q&A

解決済

1回答

318閲覧

ループの中で出力したボタンクリックのイベントの内容が複数回発生してしまうので、1回だけ出力するように修正したい

takashinago

総合スコア2

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

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

jQuery

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

0グッド

2クリップ

投稿2022/04/26 02:31

現在、Javascript(jQueryが混じっています)でファイルアップロードの機能を制作しています

以下のような内容です

Javascript

1'use strict'; 2 3let fileList = []; 4let fileCount = []; 5let fileCountMax = []; 6let file = []; 7 8// HTML文字列の生成 9let fileListBody = []; 10 11// 一部のクラスを配列化 12let formFile = document.getElementsByClassName('formFile'); 13formFile = Array.from(formFile); 14let countMax = document.getElementsByClassName('count-max'); 15countMax = Array.from(countMax); 16 17//input#formFileのfileCountMax属性の数を取得、最大アップロード数に設定 18formFile.forEach(function (element, index) { 19 20 fileCountMax[index] = element.getAttribute("fileCountMax"); 21 22 // 最大アップロード数を表示 23 countMax[index].innerHTML = fileCountMax[index]; 24 25}) 26 27// エラーメッセージの用意 28let formFileError = document.getElementsByClassName("formFileError"); 29formFileError = Array.from(formFileError); 30function ErrorMsg(number) { 31 32 formFileError[number].innerHTML = 'あと<span class="text-danger">' + (fileCount[number] - fileCountMax[number]) + '件</span>削除してください。'; 33 return; 34 35} 36 37formFile.forEach(function (element, index) { 38 39 element.addEventListener('change', function (e) { 40 41 let selectFile = e.target; 42 43 onFileUpload(selectFile, index); 44 e.target.value = ''; 45 46 fileDelete(); 47 48 }); 49 50}); 51 52//添付ファイル 53function onFileUpload(selectFile, number) { 54 55 // ファイルリストを取得 56 fileList[number] = selectFile.files; 57 fileList[number] = Array.from(fileList[number]); 58 59 60 // ファイルの数を取得 61 fileCount[number] = fileList[number].length; 62 63 fileListBody[number] = "アップロードするファイル数 = " + fileCount[number] + "/" + fileCountMax[number] + "<br/><br/>\r\n"; 64 65 // 選択されたファイルの数だけ処理する 66 for (let i = 0; i < fileCount[number]; i++) { 67 68 // ファイルを取得 69 file[number] = fileList[number][i]; 70 71 fileListBody[number] += '<li><span class="delete-file" id="' + i + '">' + file[number].name + '<span class="delete-text text-danger"> 削除</span></span></li>\r\n'; 72 73 } 74 75 // アップロード上限を超えた場合アラートを表示(必要なければコメントアウト) 76 if (fileCount[number] > fileCountMax[number]) { 77 //alert('最大アップロード数を超過しています。\n\n最大アップロード数:' + fileCountMax + '。\n現在選択中のファイル' + fileCount + '件。\n' + (fileCount - fileCountMax) + '件を削除してください。'); 78 alert('最大アップロード数を超過しています。'); 79 ErrorMsg(number); 80 } 81 82 // 結果のHTMLを流し込む 83 let fileListInner = document.getElementsByClassName('file-list'); 84 fileListInner = Array.from(fileListInner); 85 fileListInner[number].innerHTML = fileListBody[number]; 86 87 let countInner = document.getElementsByClassName('count'); 88 countInner = Array.from(countInner); 89 countInner[number].innerHTML = fileCount[number]; 90 91 let countMaxInner = document.getElementsByClassName('count-max'); 92 countMaxInner = Array.from(countMaxInner); 93 countMaxInner[number].innerHTML = fileCountMax[number]; 94 95} 96 97function fileDelete() { 98 99 let fileListContainer = $('.file-list'); 100 fileListContainer.each(function (indexA, elementA) { 101 $(elementA).find('.delete-file').each(function (indexB, elementB) { 102 $(elementB).on("click", function () { 103 104 $(this).parent().remove(); 105 fileCount[indexA]--; 106 fileList[indexA].splice(indexB, 1); 107 fileListBody[indexA] = "アップロードするファイル数 = " + fileCount[indexA] + "/" + fileCountMax[indexA] + "<br/><br/>\r\n"; 108 109 // エラーメッセージの件数の更新 110 if ((fileCount[indexA] > fileCountMax[indexA]) > 0) { 111 112 ErrorMsg(indexA); 113 114 } else { 115 116 formFileError[indexA].innerHTML = ""; 117 118 } 119 120 for (let i = 0; i < fileCount[indexA]; i++) { 121 122 // ファイルを取得 123 file[indexA] = fileList[indexA][i]; 124 fileListBody[indexA] += '<li><span class="delete-file" id="' + i + '">' + file[indexA].name + '<span class="delete-text text-danger"> 削除</span></span></li>\r\n'; 125 126 } 127 128 // 結果のHTMLを流し込む 129 let fileListInner = document.getElementsByClassName('file-list'); 130 fileListInner = Array.from(fileListInner); 131 fileListInner[indexA].innerHTML = fileListBody[indexA]; 132 133 let countInner = document.getElementsByClassName('count'); 134 countInner = Array.from(countInner); 135 countInner[indexA].innerHTML = fileCount[indexA]; 136 137 let countMaxInner = document.getElementsByClassName('count-max'); 138 countMaxInner = Array.from(countMaxInner); 139 countMaxInner[indexA].innerHTML = fileCountMax[indexA]; 140 141 fileDelete(); 142 143 }); 144 145 }); 146 147 }); 148 149} 150 151

html

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <title>File Upload</title> 7</head> 8<body> 9 10 11<main class="main mt-5 px-6"> 12 13 <div class="mb-3 row justify-content-between"> 14 <p class="col-3 fw-bold">添付ファイル</p> 15 <div class="col-8"> 16 <label for="formFile" class="btn btn-primary">ファイル選択</label> 17 <!-- ↓fileCountMax="10"が最大アップロード数 --> 18 <!-- <input class="" type="file" id="formFile" fileCountMax="10" onchange="onFileUpload( this );" multiple> --> 19 <input class="formFile" type="file" id="formFile" fileCountMax="10" multiple> 20 <span class="d-ib ms-3">アップロードするファイル数<span class="text-danger"><span class="count">0</span>/<span class="count-max">0</span></span></span> 21 <div class="ms-3 formFileError"></div> 22 <p class="message"></p> 23 <ul class="file-list" class="mt-2 list-unstyled"> 24 </ul> 25 </div> 26 </div> 27 28 <div class="mb-3 row justify-content-between"> 29 <p class="col-3 fw-bold">添付ファイル</p> 30 <div class="col-8"> 31 <label for="formFile2" class="btn btn-primary">ファイル選択</label> 32 <!-- ↓fileCountMax="10"が最大アップロード数 --> 33 <!-- <input class="" type="file" id="formFile" fileCountMax="10" onchange="onFileUpload( this );" multiple> --> 34 <input class="formFile" type="file" id="formFile2" fileCountMax="10" multiple> 35 <span class="d-ib ms-3">アップロードするファイル数<span class="text-danger"><span class="count">0</span>/<span class="count-max">0</span></span></span> 36 <div class="ms-3 formFileError"></div> 37 <p class="message"></p> 38 <ul class="file-list" class="mt-2 list-unstyled"> 39 </ul> 40 </div> 41 </div> 42 43 <div class="mb-3 row justify-content-between"> 44 <p class="col-3 fw-bold">添付ファイル</p> 45 <div class="col-8"> 46 <label for="formFile3" class="btn btn-primary">ファイル選択</label> 47 <!-- ↓fileCountMax="10"が最大アップロード数 --> 48 <!-- <input class="" type="file" id="formFile" fileCountMax="10" onchange="onFileUpload( this );" multiple> --> 49 <input class="formFile" type="file" id="formFile3" fileCountMax="10" multiple> 50 <span class="d-ib ms-3">アップロードするファイル数<span class="text-danger"><span class="count">0</span>/<span class="count-max">0</span></span></span> 51 <div class="ms-3 formFileError"></div> 52 <p class="message"></p> 53 <ul class="file-list" class="mt-2 list-unstyled"> 54 </ul> 55 </div> 56 </div> 57 58</main> 59 60<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> 61<script src="../fileupload/file_upload.js"></script> 62</body> 63</html>

このような記述なのですが、
1つ目の添付ファイルでファイルを追加、
その後、2つ目の添付ファイルを追加、
その次に、1つ目の添付ファイルに戻ってファイルを削除すると、
1つ目のファイルアップロード数のカウントが1つずつ減らずに、
2つ、4つとカウントが減っていきます
また、その逆のパターンもあります

原因を特定しようと
$(elementB).on("click", function () {
の後に、console.log("テスト")を設置してみると複数回console.logが発生しているようです

fileDelete()を、
formFile.forEach(function (element, index) {
の外に設置して、中身をまっさらな状態でテストしてみたところ、イベントは1回だけの出力となるのですが、
$(elementB).on("click", function () {
の中身はどうすれば一回だけの出力に修正、各ファイルのアップロード数も正常なカウントに修正できますでしょうか
よろしくお願いいたします

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

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

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

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

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

guest

回答1

0

ベストアンサー

js

1 element.addEventListener('change', function (e) { 2 3 let selectFile = e.target; 4 5 onFileUpload(selectFile, index); 6 e.target.value = ''; 7 8 fileDelete(); 9 10 });

となっていますから、ファイルが追加されるたびにfileDeleteが呼ばれます。

そして、

js

1 let fileListContainer = $('.file-list'); 2 fileListContainer.each(function (indexA, elementA) { 3 $(elementA).find('.delete-file').each(function (indexB, elementB) { 4 $(elementB).on("click", function () {

となっていますから、ファイルが追加されていないものも含め、全ての.delete-fileについてクリックイベントが設定されます。
これが原因ではないかと思います。

解決方法ですが、fileListContainer.eachをやめて、fileDelete(selectFile)のように対象の要素を渡してはいかがでしょうか。

投稿2022/04/26 10:01

Lhankor_Mhy

総合スコア35860

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

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

takashinago

2022/04/27 04:46

ありがとうございます! 教えていただいた方法を基本として、 記述の仕方を変更してみたところ正常に動作するように修正できました! 本当にありがとうございます
Lhankor_Mhy

2022/04/27 04:47

お役に立てたようで何よりです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問