Added the code
This commit is contained in:
committed by
GitHub
parent
2c7f8893ca
commit
bdb2833aa2
244
speedtest.htm
Normal file
244
speedtest.htm
Normal file
@@ -0,0 +1,244 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Speedtest</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<style>
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
font-size: 10px;
|
||||
background-color: #e1fff2;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
#wrap {
|
||||
position: absolute;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
margin-left: -100px;
|
||||
margin-top: -100px;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
background-color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
button {
|
||||
padding: 0.8rem;
|
||||
border: 0;
|
||||
background-color: #fff;
|
||||
font-weight: bold;
|
||||
}
|
||||
button.choice {
|
||||
background-color: #ffc800;
|
||||
}
|
||||
progress {
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
-webkit-appearance: none;
|
||||
visibility: hidden;
|
||||
}
|
||||
progress::-webkit-progress-bar {
|
||||
background-color: #b4ffe0;
|
||||
}
|
||||
progress::-webkit-progress-value {
|
||||
background-color:#00ff9a;
|
||||
}
|
||||
#result {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
#resultDone {
|
||||
font-size: 2rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
#eta {
|
||||
font-size: 1rem;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrap">
|
||||
<p>
|
||||
<button data-file="1mb.bin">1 MB</button>
|
||||
<button data-file="5mb.bin">5 MB</button>
|
||||
<button data-file="10mb.bin">10 MB</button>
|
||||
<button data-file="100mb.bin">100 MB</button>
|
||||
<button data-file="1000mb.bin">1000 MB</button>
|
||||
</p>
|
||||
<p>
|
||||
<progress value="0" max="100"></progress>
|
||||
</p>
|
||||
<p>
|
||||
<span id="result">speedtest</span><br>
|
||||
<span id="eta">choose a size</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// global vars
|
||||
let req;
|
||||
let start = 0;
|
||||
let count = 0;
|
||||
let sum = 0;
|
||||
let decimals = 0;
|
||||
|
||||
// control precision
|
||||
function onKeyDown (ev) {
|
||||
switch (ev.code) {
|
||||
case 'ArrowUp':
|
||||
case 'ArrowRight':
|
||||
decimals++;
|
||||
decimals = decimals > 3 ? 3 : decimals;
|
||||
break;
|
||||
|
||||
case 'ArrowDown':
|
||||
case 'ArrowLeft':
|
||||
decimals--;
|
||||
decimals = decimals < 0 ? 0 : decimals;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener ('keydown', onKeyDown);
|
||||
|
||||
// store <button> tags in array
|
||||
const btns = Array.from (document.querySelectorAll ('button'));
|
||||
|
||||
// add click handler to buttons
|
||||
btns.forEach (btn => {
|
||||
btn.addEventListener ('click', testDownload);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Round number to defined decimals
|
||||
*
|
||||
* @param {number} num Number to round
|
||||
* @param {number} deci Number of decimals to round to
|
||||
* @return {string} Rounded number with trailing zeros
|
||||
*/
|
||||
|
||||
function dec (num, deci) {
|
||||
let amount;
|
||||
let result;
|
||||
let missing;
|
||||
let i;
|
||||
|
||||
// rounding
|
||||
if (deci) {
|
||||
amount = Math.pow (10, deci || 1);
|
||||
result = Math.round (num * amount) / amount;
|
||||
} else {
|
||||
result = Math.round (num);
|
||||
}
|
||||
|
||||
// force trailing zeros
|
||||
result = String (result);
|
||||
|
||||
if (!deci) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (deci && !~result.indexOf ('.')) {
|
||||
missing = deci;
|
||||
result += '.';
|
||||
} else {
|
||||
missing = deci - result.split ('.')[1].length;
|
||||
}
|
||||
|
||||
if (missing) {
|
||||
for (i = missing; i > 0; i--) {
|
||||
result += '0';
|
||||
}
|
||||
}
|
||||
|
||||
// done
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test completed
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
|
||||
function testDone () {
|
||||
const diff = dec ((Date.now() - start) / 1000, 2);
|
||||
|
||||
document.querySelector ('progress').style.visibility = 'hidden';
|
||||
document.querySelector ('#result').className = 'resultDone';
|
||||
document.querySelector ('#eta').innerHTML = diff + ' sec';
|
||||
req = null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test progress handler
|
||||
*
|
||||
* @param {Event} ev XMLHttpRequest.onprogress event
|
||||
* @return {void}
|
||||
*/
|
||||
|
||||
function testRunning (ev) {
|
||||
const now = Date.now ();
|
||||
|
||||
let percent = 0.0;
|
||||
let Bps = 0;
|
||||
let avg = 0;
|
||||
let eta = 0;
|
||||
|
||||
if (ev.lengthComputable && ev.total > 0) {
|
||||
Bps = ev.loaded / ((now - start) / 1000);
|
||||
mbit = Bps / 1024 / 1024 * 8;
|
||||
count++;
|
||||
sum += mbit;
|
||||
avg = sum / count;
|
||||
percent = ev.loaded / ev.total * 100.0;
|
||||
eta = (ev.total - ev.loaded) / Bps;
|
||||
}
|
||||
|
||||
document.querySelector ('progress').value = percent;
|
||||
document.querySelector ('#result').innerHTML = dec (avg, decimals) + ' Mbit/s';
|
||||
document.querySelector ('#eta').innerHTML = dec (eta, decimals) + ' sec';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Start new test
|
||||
* and abort any running test
|
||||
*
|
||||
* @param {Event} ev Click event
|
||||
* @return {void}
|
||||
*/
|
||||
|
||||
function testDownload (ev) {
|
||||
if (req) {
|
||||
req.abort ();
|
||||
}
|
||||
|
||||
req = new XMLHttpRequest ();
|
||||
|
||||
start = Date.now ();
|
||||
count = 0;
|
||||
sum = 0;
|
||||
|
||||
btns.forEach (btn => {
|
||||
btn.className = '';
|
||||
});
|
||||
|
||||
ev.target.className = 'choice';
|
||||
document.querySelector ('progress').style.visibility = 'visible';
|
||||
|
||||
req.onreadystatechange = () => {
|
||||
if (req.readyState === 4) {
|
||||
testDone ();
|
||||
}
|
||||
};
|
||||
|
||||
req.onprogress = testRunning;
|
||||
req.open ('GET', ev.target.dataset.file + '?' + start, true);
|
||||
req.send (null);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user