Reputation: 67
This is my Fiddle: https://jsfiddle.net/e6b5hdow/2/
const links = document.querySelectorAll('[href$=".jpg"], [href$=".png"], [href$=".mp4"], [href$=".avi"], [href$=".jpeg"], [href$=".mkv"], [href$=".csv"]');
links.forEach(link => link.classList.add('download-button'));
$('.name').prepend($("<div class='download-ui-container'><div class='start-download'>Starting Download..</div><div class='download-progress-container'><div class='download-progress'></div></div><a class='save-file'>Save File</a></div>"));
var _OBJECT_URL;
$(document).on('click', '.download-button', function(event) {
var request = new XMLHttpRequest();
fileDownload = $(this).attr('href');
var _t = $(this);
request.addEventListener('readystatechange', function(e) {
if (request.readyState == 2 && request.status == 200) {
_t.parents('td').find('.start-download').css('display', 'block');
_t.parents('td').find('.download-button').hide();
} else if (request.readyState == 3) {
_t.parents('td').find('.download-progress-container').css('display', 'block');
_t.parents('td').find('.start-download').hide()
} else if (request.readyState == 4) {
_OBJECT_URL = URL.createObjectURL(request.response);
var fileName = fileDownload.split("/")
fileName = fileName[fileName.length - 1]
var downloadLink = document.createElement('a');
console.log(downloadLink);
downloadLink.href = _OBJECT_URL;
downloadLink.download = fileName;
// document.body.appendChild(downloadLink);
downloadLink.click();
_t.parents('td').find('.download-button').css('display', 'block');
_t.parents('td').find('.download-progress-container').hide();
_t.parents('td').find('.save-file').click();
setTimeout(function() {
window.URL.revokeObjectURL(_OBJECT_URL);
_t.parents('td').find('.download-button').css('display', 'block');
_t.parents('td').find('.save-file').css('display', 'hide');
}, 60 * 1000);
}
});
request.addEventListener('progress', function(e) {
var percent_complete = (e.loaded / e.total) * 100;
_t.parents('td').find('.download-progress').css('width', percent_complete + '%');
});
request.responseType = 'blob';
request.open('get', fileDownload);
request.send();
return false;
});
.demo-container {
width: 400px;
margin: 60px auto;
}
.download-button {
background-color: white;
color: #2980b9;
border: 2px solid #2980b9;
font-family: inherit;
outline: none;
min-width: 100px;
padding: 10px;
font-size: inherit;
border-radius: 2px;
cursor: pointer;
display: block;
margin: 0 auto;
}
.start-download {
text-align: center;
display: none;
}
.download-progress-container {
border: 1px solid #cccccc;
padding: 4px;
display: none;
height: 20px;
}
.download-progress {
background-color: #2980b9;
display: inline-block;
height: 100%;
}
.save-file {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<table>
<tr>
<td class="name">
<a href="https://upload.wikimedia.org/wikipedia/commons/9/9b/Sternwarte_Darmstadt_HDR_Panorama_10MB_-_Photographed_by_James_Breitenstein.jpg">First link, large file</a>
</td>
</tr>
<tr>
<br><br><br>
<td class="name">
<a href="https://images.pexels.com/photos/414612/pexels-photo-414612.jpeg">Second link small file</a>
</td>
</tr>
</table>
Here, I am trying to download the file using Ajax and show progress bar. It works perfectly but one problem.
If the first link file is big, and second link file is small.
Then if someone clicks on the first link and file starts downloading and
then immediately clicks on second link and file downloads because of small size, and first link file is still downloading.
After the first link click file is downloaded, it saves with the file with name of second file.
Reproducing steps:
Click on first link Click on second link If second link file downloads first, then the name of first link file is same as of second file link
I think, when I call the function again, the filename
variable, it gets overwritten something.
Is it possible to use request header instead of filename?
Basically, what I need is.
A way to prevent the overwrite of variable name, when a function is called two times with different parameters, and the function called first time, takes longer to execute, and function called second time, executes within 1 sec.
Upvotes: 1
Views: 81
Reputation: 513
just replace
fileDownload = $(this).attr('href');
with
var fileDownload = $(this).attr('href');
so that your variable is not considered global by javascript
Upvotes: 1