そのため、多数のファイルへのリンクを持つhttpdサーバーを実行しています。ユーザーがダウンロードするファイルリストから3つのファイルを選択し、それらが次の場所にあるとします。
mysite.com/file1
mysite.com/file2
mysite.com/file3
ダウンロードボタンをクリックすると、上記のリンクからこれら3つのファイルをダウンロードするようになります。
ダウンロードボタンは次のようになります。
var downloadButton = new Ext.Button({
text: "Download",
handler: function(){
//download the three files here
}
});
これを行うための最良の方法は、ファイルを圧縮し、それにリンクすることです。
他の解決策はここにあります: リンクをクリックして複数のページを開く方法
次のように述べています:
HTML:
<a href="#" class="yourlink">Download</a>
JS:
$('a.yourlink').click(function(e) {
e.preventDefault();
window.open('mysite.com/file1');
window.open('mysite.com/file2');
window.open('mysite.com/file3');
});
このことを言っても、この実装にはJavaScriptが必要であり、ポップアップとしてブロックされることもあるため、ファイルの圧縮を続けます。
これは私にとって最適な方法であり、新しいタブを開かず、必要なファイル/画像をダウンロードしただけでした:
var filesForDownload = [];
filesForDownload( { path: "/path/file1.txt", name: "file1.txt" } );
filesForDownload( { path: "/path/file2.jpg", name: "file2.jpg" } );
filesForDownload( { path: "/path/file3.png", name: "file3.png" } );
filesForDownload( { path: "/path/file4.txt", name: "file4.txt" } );
$jq('input.downloadAll').click( function( e )
{
e.preventDefault();
var temporaryDownloadLink = document.createElement("a");
temporaryDownloadLink.style.display = 'none';
document.body.appendChild( temporaryDownloadLink );
for( var n = 0; n < filesForDownload.length; n++ )
{
var download = filesForDownload[n];
temporaryDownloadLink.setAttribute( 'href', download.path );
temporaryDownloadLink.setAttribute( 'download', download.name );
temporaryDownloadLink.click();
}
document.body.removeChild( temporaryDownloadLink );
} );
次のいずれかを実行できます。
注-オプション1は客観的に優れています。
Editオプション3を見つけました: https://stackoverflow.com/a/9425731/1803682
<!DOCTYPE html>
<html ng-app='app'>
<head>
<title>
</title>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<link rel="stylesheet" href="style.css">
</head>
<body ng-cloack>
<div class="container" ng-controller='FirstCtrl'>
<table class="table table-bordered table-downloads">
<thead>
<tr>
<th>Select</th>
<th>File name</th>
<th>Downloads</th>
</tr>
</thead>
<tbody>
<tr ng-repeat = 'tableData in tableDatas'>
<td>
<div class="checkbox">
<input type="checkbox" name="{{tableData.name}}" id="{{tableData.name}}" value="{{tableData.name}}" ng-model= 'tableData.checked' ng-change="selected()">
</div>
</td>
<td>{{tableData.fileName}}</td>
<td>
<a target="_self" id="download-{{tableData.name}}" ng-href="{{tableData.filePath}}" class="btn btn-success pull-right downloadable" download>download</a>
</td>
</tr>
</tbody>
</table>
<a class="btn btn-success pull-right" ng-click='downloadAll()'>download selected</a>
<p>{{selectedone}}</p>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="script.js"></script>
</body>
</html>
app.js
var app = angular.module('app', []);
app.controller('FirstCtrl', ['$scope','$http', '$filter', function($scope, $http, $filter){
$scope.tableDatas = [
{name: 'value1', fileName:'file1', filePath: 'data/file1.txt', selected: true},
{name: 'value2', fileName:'file2', filePath: 'data/file2.txt', selected: true},
{name: 'value3', fileName:'file3', filePath: 'data/file3.txt', selected: false},
{name: 'value4', fileName:'file4', filePath: 'data/file4.txt', selected: true},
{name: 'value5', fileName:'file5', filePath: 'data/file5.txt', selected: true},
{name: 'value6', fileName:'file6', filePath: 'data/file6.txt', selected: false},
];
$scope.application = [];
$scope.selected = function() {
$scope.application = $filter('filter')($scope.tableDatas, {
checked: true
});
}
$scope.downloadAll = function(){
$scope.selectedone = [];
angular.forEach($scope.application,function(val){
$scope.selectedone.Push(val.name);
$scope.id = val.name;
angular.element('#'+val.name).closest('tr').find('.downloadable')[0].click();
});
}
}]);
プランカーの例: https://plnkr.co/edit/XynXRS7c742JPfCA3IpE?p=preview
Window.locationを使用して、これを別の方法で解決しました。 Chromeで動作します。Chromeは幸いなことに、サポートする必要がある唯一のブラウザです。誰かに役立つかもしれません。私は最初にダンの答えを使用しましたが、これにはここで使用したタイムアウトも必要でした。または、ファイルを1つだけダウンロードしました。
var linkArray = [];
linkArray.Push("http://example.com/downloadablefile1");
linkArray.Push("http://example.com/downloadablefile2");
linkArray.Push("http://example.com/downloadablefile3");
function (linkArray) {
for (var i = 0; i < linkArray.length; i++) {
setTimeout(function (path) { window.location = path; }, 200 + i * 200, linkArray[i]);
}
};
複数のファイルをダウンロードするために_for loop
_内のa
要素でclick()
イベントを実行すると、限られた数のファイル(私の場合は10個のファイル)でしか動作しません。私にとって意味のあるこの動作を説明する唯一の理由は、click()
イベントによって実行されるダウンロードの速度/間隔です。
click()
イベントの実行を遅くすると、すべてのファイルをダウンロードできるようになります。
これは私のために働いた解決策です。
_var urls = [
'http://example.com/file1',
'http://example.com/file2',
'http://example.com/file3'
]
var interval = setInterval(download, 300, urls);
function download(urls) {
var url = urls.pop();
var a = document.createElement("a");
a.setAttribute('href', url);
a.setAttribute('download', '');
a.setAttribute('target', '_blank');
a.click();
if (urls.length == 0) {
clearInterval(interval);
}
}
_
ダウンロードイベントclick()
を300ミリ秒ごとに実行します。 _urls.length == 0
_をダウンロードするファイルがなくなったら、clearInterval
関数でinterval
を実行してダウンロードを停止します。
これはすべてのブラウザー(IE11、Firefox、Microsoft Edge、ChromeおよびChromeモバイル)で動作します。私のドキュメントには複数の選択要素があります。あなたがそれをあまりにも速くしようとするとき...だから私はタイムアウトを使用しました。
<select class="document">
<option val="Word.docx">some Word document</option>
</select>
//user clicks a download button to download all selected documents
$('#downloadDocumentsButton').click(function () {
var interval = 1000;
//select elements have class name of "document"
$('.document').each(function (index, element) {
var doc = $(element).val();
if (doc) {
setTimeout(function () {
window.location = doc;
}, interval * (index + 1));
}
});
});
このソリューションは約束を使用します:
function downloadDocs(docs) {
docs[0].then(function (result) {
if (result.web) {
window.open(result.doc);
}
else {
window.location = result.doc;
}
if (docs.length > 1) {
setTimeout(function () { return downloadDocs(docs.slice(1)); }, 2000);
}
});
}
$('#downloadDocumentsButton').click(function () {
var files = [];
$('.document').each(function (index, element) {
var doc = $(element).val();
var ext = doc.split('.')[doc.split('.').length - 1];
if (doc && $.inArray(ext, docTypes) > -1) {
files.unshift(Promise.resolve({ doc: doc, web: false }));
}
else if (doc && ($.inArray(ext, webTypes) > -1 || ext.includes('?'))) {
files.Push(Promise.resolve({ doc: doc, web: true }));
}
});
downloadDocs(files);
});
それを行うには、マウスイベントを作成し、ボタンにディスパッチします。 ソース
hrefList=['mysite.com/1.jpg', 'mysite.com/2.mp4', 'mysite.com/3.gif'];
buttonDownloadAll=document.createElement('a');
buttonDownloadAll.innerText='Download all';
buttonDownloadAll.href='';
buttonDownloadAll.download=false;
downloadFunc=function(){
buttonDownloadAll.setAttribute('onclick', '');
buttonDownloadAll.download=true;
for(var i=0; i<hrefList.length-1; i++){
buttonDownloadAll.href=hrefList[i];
var clickEvent = document.createEvent('MouseEvent');
clickEvent.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
buttonDownloadAll.dispatchEvent(clickEvent);
}
buttonDownloadAll.setAttribute('onclick', 'downloadFunc()');
buttonDownloadAll.download=false;
buttonDownloadAll.href='';
};
buttonDownloadAll.setAttribute('onclick', 'downloadFunc()');
document.body.appendChild(buttonDownloadAll);