Ich habe also einen httpd-Server, der Links zu einer Reihe von Dateien hat. Angenommen, der Benutzer wählt drei Dateien aus einer Dateiliste zum Herunterladen aus, und diese befinden sich unter:
mysite.com/file1
mysite.com/file2
mysite.com/file3
Wenn sie auf den Download-Button klicken, möchte ich, dass sie diese drei Dateien von den oben genannten Links herunterladen.
Mein Download-Button sieht ungefähr so aus:
var downloadButton = new Ext.Button({
text: "Download",
handler: function(){
//download the three files here
}
});
Der beste Weg, dies zu tun, ist, Ihre Dateien zu komprimieren und darauf zu verlinken:
Die andere Lösung finden Sie hier: Wie kann man einen Link beim Klick auf mehrere Seiten öffnen lassen
Welches besagt folgendes:
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');
});
Trotzdem würde ich immer noch mit dem Zippen der Datei gehen, da diese Implementierung JavaScript erfordert und manchmal auch als Popups blockiert werden kann.
Dies war die Methode, die am besten für mich funktionierte und keine neuen Registerkarten öffnete, sondern nur die benötigten Dateien/Bilder heruntergeladen hat:
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 );
} );
Du kannst entweder:
Hinweis - Option eins ist objektiv besser.
Edit Eine dritte Option gefunden: 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();
});
}
}]);
plunker-Beispiel: https://plnkr.co/edit/XynXRS7c742JPfCA3IpE?p=preview
Ich habe dies anders gelöst, indem ich window.location verwende. Es funktioniert in Chrome, was zum Glück der einzige Browser ist, den ich unterstützen musste. Könnte jemandem nützlich sein. Ursprünglich hatte ich Dans Antwort verwendet, die auch das Timeout benötigte, das ich hier verwendet hatte, oder es wurde nur eine Datei heruntergeladen.
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]);
}
};
Sie können dies tun, indem Sie Mausereignisse erstellen und sie an die Schaltfläche senden. Sourse.
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);
Ich finde, dass das Ausführen des click()
-Ereignisses auf dem a
-Element innerhalb eines for loop
für das Herunterladen mehrerer Dateien nur für eine begrenzte Anzahl von Dateien (in meinem Fall 10 Dateien) funktioniert. Der einzige Grund, der für mich Sinn machte, war das Herunterladen von Ereignissen.
Die Lösung, die für mich funktionierte, bestand darin, die Ausführung von click()
event zu verlangsamen. Ich habe dies mit dem folgenden Quellcode erreicht.
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);
}
}
Ich führe alle 300ms das Downloadereignis click()
aus. Wenn keine weiteren Dateien zum Herunterladen von urls.length == 0
vorhanden sind, führe ich clearInterval
für die Funktion interval
aus.
Dies funktioniert in allen Browsern (IE11, Firefox, Microsoft Edge, Chrome und Chrome Mobile). Meine Dokumente bestehen aus mehreren Auswahlelementen. Die Browser scheinen Probleme zu haben, wenn Sie versuchen, dies zu schnell zu tun ... Also habe ich ein Timeout verwendet.
<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));
}
});
});
Diese Lösung verwendet Versprechen:
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);
});