Chunk Uploads w/ XHR
by gavinfoley
HTML
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/foundation/4.3.1/css/normalize.css">
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/foundation/4.3.1/css/foundation.css">
<div class="row">
<div class="large-12 column">
<p>Chunk Size: 1mb (1048576 bytes)</p>
<input type="number" min="1048576" value="1048576" id="numChunks" />
<input type="file" id="afile" />
<div id="done"></div>
<div id="bars"></div>
</div>
</div>
CSS
.progress {
color:#fff;
}
.meter {
width:0%;
font-size: 12px;
padding: .3em;
}
JavaScript
(function () {
'use strict';
var bars = document.getElementById('bars'),
uploaders = [],
upload,
chooseFile;
upload = function (blobOrFile) {
var progress = document.createElement('div'),
meter = document.createElement('span'),
xhr;
progress.classList.add('progress');
meter.classList.add('meter');
bars.appendChild(progress);
progress.appendChild(meter);
xhr = new XMLHttpRequest();
xhr.open('POST', '/echo/json/', true);
xhr.upload.onprogress = function (e) {
if (e.lengthComputable) {
meter.value = Math.round((e.loaded / e.total) * 100);
meter.textContent = parseFloat(meter.value) + '%';
meter.style.width = meter.textContent;
}
if (meter.textContent === '100%') progress.classList.add('success');
};
xhr.onloadend = function (e) {
uploaders.pop();
if (!uploaders.length) {
bars.appendChild(document.createTextNode(' All Done! '));
}
};
uploaders.push(xhr);
xhr.send(blobOrFile);
};
chooseFile = document.getElementById('afile');
chooseFile.addEventListener('change', function (e) {
var self = e.currentTarget,
blob = self.files[0],
BYTES_PER_CHUNK, SIZE, NUM_CHUNKS, start, end;
BYTES_PER_CHUNK = parseInt(document.getElementById('numChunks').value, 10);
SIZE = blob.size;
NUM_CHUNKS = Math.max(Math.ceil(SIZE / BYTES_PER_CHUNK), 1);
bars.innerHTML = '';
bars.innerHTML = '<p>Sending <b>' + NUM_CHUNKS + '</b> chunks:</p>';
start = 0;
end = BYTES_PER_CHUNK;
while (start < SIZE) {
upload(blob.slice(start, end));
start = end;
end = start + BYTES_PER_CHUNK;
}
}, false);
...