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

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

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

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

jQuery

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

2回答

985閲覧

【HTML/CSS/JavaScript】初回押下でダウンロードが開始しない

street

総合スコア34

JavaScript

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

jQuery

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

1クリップ

投稿2017/11/23 05:46

お世話になります。
CSVファイルへ変換したファイルをダウンロードする処理を実装していますが、
なぜか初回押下でダウンロードが開始されません。
手順は以下の通りです。

  1. ローカル上から箇条書きに書かれたテキストファイルを用意.
  2. 「ファイルを選択」よりtest.txtを選択.
  3. 「CSVファイルに変換する」を押下.
    → 読み込み中の画像は表示されるがダウンロードが始まらない。2回押下以降でダウンロードが開始される。

HTML/CSS/JavaScriptのコードとテキストファイルは以下の通りです。
お手数ですが実装誤り等があればご教示お願いいたします。

HTML

1<!DOCTYPE html> 2<html> 3<head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 5 <title>タイトル</title> 6 <script src="https://code.jquery.com/jquery-3.0.0.min.js"></script> 7 <script type="text/javascript"> 8 9 function OnButtonClick(isExport) { 10 var fileRef = document.getElementById('File1'); 11 if ("" != fileRef.value) { 12 GetFileData_(isExport, function(result) { 13 // 読み込み中をストップ. 14 $('#loader-bg').delay(900).fadeOut(800); 15 $('#loader').delay(600).fadeOut(300); 16 $('#output').css('display','block'); 17 }); 18 // ■ 読み込み中を表示. 19 var h = $(window).height(); 20 $('#output').css('display','none'); 21 $('#loader-bg, #loader').height(h).css('display', 'block'); 22 } else { 23 alert("ファイルを選択してください.") 24 } 25 } 26 27 function csvDownload_(exportData) { 28 var bom = new Uint8Array([0xEF, 0xBB, 0xBF]); 29 var content = exportData; 30 var blob = new Blob([ bom, content ], { "type" : "text/csv" }); 31 32 var fileRef = document.getElementById('File1'); 33 var filename = fileRef.files[0].name.replace('.txt', '.csv'); 34 if (window.navigator.msSaveBlob) { 35 window.navigator.msSaveBlob(blob, filename); 36 37 // msSaveOrOpenBlobの場合はファイルを保存せずに開ける 38 window.navigator.msSaveOrOpenBlob(blob, filename); 39 alert("もう一度ダウンロードボタンを選択してください.") 40 } else { 41 document.getElementById("download_csv").download = filename; 42 document.getElementById("download_csv").href = window.URL.createObjectURL(blob); 43 } 44 } 45 46 var GetFileData_ = function(isExport, callback) { 47 var fileRef = document.getElementById('File1'); 48 var outFrame = document.getElementById('output'); 49 if (1 <= fileRef.files.length) 50 { 51 var reader = new FileReader(); 52 53 // ■ 読み込み時の処理. 54 reader.onload = function (theFile) { 55 var outhtml = theFile.target.result; 56 57 var textArray = outhtml.split(/\r\n|\r|\n/); 58 var reArray = new Array(); 59 60 for (var i=0 ; i<textArray.length ; i++) { 61 var tmp = textArray[i]; 62 if ( true == CheckCharcter_(tmp) ) reArray.push(tmp); 63 } 64 65 if ( true == isExport ) { 66 var exportData = ""; 67 for (var i=0 ; i<reArray.length ; i++) { 68 var str1 = reArray[i] + ","; 69 for (var j=0 ; j<reArray.length ; j++) { 70 if ( i != j ) { 71 var str2 = reArray[j]; 72 exportData += str1 + str2 + "\n"; 73 } 74 } 75 } 76 csvDownload_(exportData); 77 } 78 else { 79 var outputHtmlStr = "" 80 for (var i=0 ; i<reArray.length ; i++) { 81 var str1 = reArray[i] + "&nbsp;&nbsp;&nbsp;+&nbsp;&nbsp;&nbsp;"; 82 for (var j=0 ; j<reArray.length ; j++) { 83 if ( i != j ) { 84 var str2 = reArray[j] + "&nbsp;&nbsp;&nbsp;+&nbsp;&nbsp;&nbsp;"; 85 outputHtmlStr += str1 + str2 + "<br>"; 86 /* 87 for (var k=0 ; k<reArray.length ; k++) { 88 if ( (i != k) && (j != k) ){ 89 var str3 = reArray[k]; 90 outputHtmlStr += str1 + str2 + str3 + "<br>"; 91 } 92 } 93 */ 94 } 95 } 96 } 97 outFrame.innerHTML = outputHtmlStr; 98 } 99 callback("OK"); 100 } 101 102 // ■ 読み込み開始(非同期処理). 103 reader.readAsText(fileRef.files[0], "shift-jis"); 104 } 105 } 106 107 function CheckCharcter_(str) { 108 if ( ("" != str) && ("\t" != str) && 109 ( -1 == str.indexOf('■')) && ( -1 == str.indexOf('【') ) ) { 110 return true; 111 } 112 return false; 113 } 114 115 </script> 116</head> 117<style type="text/css"> 118 #loader-bg { 119 display: none; 120 position: fixed; 121 width: 100%; 122 height: 100%; 123 top: 0px; 124 left: 0px; 125 background: #000; 126 z-index: 1; 127 } 128 #loader { 129 display: none; 130 position: fixed; 131 top: 50%; 132 left: 50%; 133 width: 200px; 134 height: 200px; 135 margin-top: -100px; 136 margin-left: -100px; 137 text-align: center; 138 color: #fff; 139 z-index: 2; 140 } 141</style> 142<body> 143 <input type="file" id="File1" /> 144 <input type="button" id="Button1" value="開く" onclick="OnButtonClick(false);" /><br> 145 <a id="download_csv" href="#" onclick="OnButtonClick(true)">CSVファイルに変換する<a/> 146 <!-- <input type="button" id="download_csv" value="ダウンロード" onclick="OnButtonClick(true);" /><br> --> 147 <div id="loader-bg"> 148 <div id="loader"> 149 <img src="img/img-loading.gif" width="80" height="80" alt="Now Loading..."/> 150 <p>Now Loading...</p> 151 </div> 152 </div> 153 <div id="output"></div> 154</body> 155</html>

Text

1aaa 2bbb 3ccc 4ddd

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

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

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

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

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

guest

回答2

0

途中, FileReaderオブジェクトのreadAsTextメソッドを呼び出している部分で非同期処理が行われているからです.

すなわちa要素クリックイベントでの処理はreadAsTextメソッドの呼び出しで終了しており, 続けてブラウザ規定のリンククリック動作が発生します. この後に非同期的にFileReaderオブジェクトのloadイベントによるリンク操作処理(csvDownload_メソッドの実行=download属性の設定, CSVファイルの設定)が呼び出されています. そのため「初回押下でダウンロードが開始しない」ように見えるのです. (逆に初回の処理が残っているので2回目にダウンロード出来ているように見える)

回避策としてはooeokさんのコードの通りファイル保存専用のaを設け, clickメソッドでファイル保存動作を呼び出すのが良かろうと思います.

NOTE:
非同期処理から直接ファイル保存を行う場合, 処理に時間がかかるとa要素のclickメソッドがブラウザによりキャンセルされてしまうことがあります. セキュリティの観点からファイルの保存は明確にユーザーの意思によって行われた時に限るという縛りがあるからです(この部分ちょっと記憶が曖昧).
なので確実性を求めるのであれば(利便性と引き換えに), CSVファイルの生成処理とCSVファイルのダウンロード処理は分けた方がよいと思います.

NOTE:
なお, URL.createObjectURLで生成したURLは不必要となった時点(リンクのURLを書き換えた時点)でURL.revokeObjectURLメソッドを使って明示的に開放してあげて下さい. さもないとメモリリークを引き起こします.

投稿2017/11/23 11:38

編集2017/11/23 11:54
defghi1977

総合スコア4756

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

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

street

2017/11/23 11:50

ご回答有難うございます! 原因についても教えていただき大変勉強になります。 承知しました。今後は変換処理と保存処理を分けたいと思います。 お忙しい中有難うございました!
ooeok

2017/11/23 12:43

なるほど!勉強になりました。 同期を取ればaタグなしでいけそうですね。
guest

0

ベストアンサー

1回目と2回目のaタグの変化は以下のようでした。
読み込むファイルはdemo.txt、ブラウザはchrome62.0.3202.94を使用。

html

1(1回目) 2<a id="download_csv" href="#" onclick="OnButtonClick(true)">CSVファイルに変換する</a> 3 4(2回目) 5<a id="download_csv" href="blob:http://localhost/a45424ec-19d6-485e-bd7f-78d6b416a494" onclick="OnButtonClick(true)" download="demo.csv">CSVファイルに変換する</a>

理由は分かりませんが、最初からdownload="test.csv"を書いておけば1回目のクリックでダウンロードできました。

html

1<a id="download_csv" href="#" onclick="OnButtonClick(true)" download="test.csv">CSVファイルに変換する</a>

でもファイル名が1回目はtest.csvになってしまう(2回目はdemo.csv)。
どうもdocument.getElementById("download_csv").download = filename;に問題がありそうです。
この解決ができなかったので(どなたか解説お願いします)、あらたにaタグを追加する方法で実現してみました。

javascript

1// document.getElementById("download_csv").download = filename; 2// document.getElementById("download_csv").href = window.URL.createObjectURL(blob); 3 4 let a = document.createElement('a'); 5 a.download = filename; 6 a.target = '_blank'; 7 a.href = window.URL.createObjectURL(blob); 8 a.click();

chromeでしか試していません。
他のブラウザではwindow.URL.createObjectURL(blob)を変える必要があるでしょう。

投稿2017/11/23 10:45

ooeok

総合スコア469

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

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

street

2017/11/23 11:32

ご確認していただき有難うございます! 教えていただいた通り、aタグを生成するようにしたところ初回ダウンロードすることができました。 (_blankの記述をコメントアウトしたところsafariで動作しました) お忙しい中、有難うございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問