<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>网络实时状态</title>
<style>
.signal {
height: 30px;
width: 50px;
display: flex;
align-items: flex-end;
justify-content: space-between;
}
.signal>div {
background-color: gainsboro;
width: 22%;
}
.signal>div:nth-of-type(1) {
height: 20%;
}
.signal>div:nth-of-type(2) {
height: 46%;
}
.signal>div:nth-of-type(3) {
height: 72%;
}
.signal>div:nth-of-type(4) {
position: relative;
height: 100%;
}
.signal .noSignal {
position: absolute;
bottom: 0;
right: -10;
padding: 0 4px;
color: red;
display: none;
}
.cmd{
width: 800px;
height: 300px;
background-color: black;
color: white;
overflow-y: auto;
padding-bottom:4px ;
}
</style>
</head>
<body>
<div class="box">
<div class="signal">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item">
<div class="noSignal">x</div>
</div>
</div>
<div class="detail"></div>
<div class="cmd">http实现ping工具:</div>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.27.0/moment.min.js"></script>
<script>
// -----------------ping.js开始-------------------------------------
/**
* Creates and loads an image element by url.
* @param {String} url
* @return {Promise} promise that resolves to an image element or
* fails to an Error.
*/
function request_image(url) {
return new Promise(function (resolve, reject) {
var img = new Image();
img.onload = function () { resolve(img); };
img.onerror = function () { reject(url); };
img.src = url + '?random-no-cache=' + Math.floor((1 + Math.random()) * 0x10000).toString(16);
});
}
/**
* Pings a url.
* @param {String} url
* @param {Number} multiplier - optional, factor to adjust the ping by. 0.3 works well for HTTP servers.
* @return {Promise} promise that resolves to a ping (ms, float).
*/
function ping(url, multiplier) {
return new Promise(function (resolve, reject) {
var start = (new Date()).getTime();
var response = function () {
var delta = ((new Date()).getTime() - start);
delta *= (multiplier || 1);
resolve(delta);
};
request_image(url).then(response).catch(response);
// Set a timeout for max-pings, 5s.
setTimeout(function () { reject(Error('Timeout')); }, 5000);
});
}
// -----------------ping.js结束-------------------------------------
let cmdHtml = '';
function setSignalTip(url) {
ping(url).then(function (delta) {
if (navigator.onLine) {
const renderSgAc = (num) => {
const signalEl = document.querySelector('.signal');
signalEl.querySelectorAll('.item').forEach((item) => {
item.style.backgroundColor = 'gainsboro';
})
for (let i = 0; i < num; i++) {
signalEl.querySelectorAll('.item')[i].style.backgroundColor = 'green';
}
}
if (delta > 400) { // 网络延迟
renderSgAc(1)
} else if (delta > 300 && delta < 400) {// 网络不好
renderSgAc(2)
} else if (delta > 200 && delta <= 300) { // 网络一般
renderSgAc(3)
} else if (delta <= 200) { // 网络优秀
renderSgAc(4)
}
document.querySelector('.detail').innerHTML = `<div>
<div>网络延迟:${delta}毫秒</div>
</div>`
document.querySelector('.noSignal').style.display = 'none'
const urlObj = new URL(url);
const cmdEl = document.querySelector('.cmd');
cmdHtml = cmdEl.innerHTML+`<div>
来自 ${urlObj.host} 的回复:
<span style="width:90px; display:inline-block">耗时=${delta} </span>
<span>请求时间=${moment().format('YYYY-MM-DD HH:mm:ss')}</span>
</div>`;
cmdEl.innerHTML = cmdHtml;
cmdEl.scrollTop = cmdEl.scrollHeight;
} else {
const signalEl = document.querySelector('.signal');
signalEl.querySelectorAll('.item').forEach((item) => {
item.style.backgroundColor = 'gainsboro';
})
document.querySelector('.detail').innerHTML = `<div>
<div>网络延迟:err毫秒</div>
<div>网络错误</div>
</div>`
document.querySelector('.noSignal').style.display = 'block'
}
}).catch(function (err) {
const signalEl = document.querySelector('.signal');
signalEl.querySelectorAll('.item').forEach((item) => {
item.style.backgroundColor = 'gainsboro';
})
document.querySelector('.detail').innerHTML = `<div>
<div>网络延迟:err毫秒</div>
<div>网络错误</div>
</div>`
document.querySelector('.noSignal').style.display = 'block'
});
}
setSignalTip('服务器文件地址')
setInterval(() => {
setSignalTip('服务器文件地址')
}, 1000)
</script>
</body>
</html>