1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    6. <title>网络实时状态</title>
    7. <style>
    8. .signal {
    9. height: 30px;
    10. width: 50px;
    11. display: flex;
    12. align-items: flex-end;
    13. justify-content: space-between;
    14. }
    15. .signal>div {
    16. background-color: gainsboro;
    17. width: 22%;
    18. }
    19. .signal>div:nth-of-type(1) {
    20. height: 20%;
    21. }
    22. .signal>div:nth-of-type(2) {
    23. height: 46%;
    24. }
    25. .signal>div:nth-of-type(3) {
    26. height: 72%;
    27. }
    28. .signal>div:nth-of-type(4) {
    29. position: relative;
    30. height: 100%;
    31. }
    32. .signal .noSignal {
    33. position: absolute;
    34. bottom: 0;
    35. right: -10;
    36. padding: 0 4px;
    37. color: red;
    38. display: none;
    39. }
    40. .cmd{
    41. width: 800px;
    42. height: 300px;
    43. background-color: black;
    44. color: white;
    45. overflow-y: auto;
    46. padding-bottom:4px ;
    47. }
    48. </style>
    49. </head>
    50. <body>
    51. <div class="box">
    52. <div class="signal">
    53. <div class="item"></div>
    54. <div class="item"></div>
    55. <div class="item"></div>
    56. <div class="item">
    57. <div class="noSignal">x</div>
    58. </div>
    59. </div>
    60. <div class="detail"></div>
    61. <div class="cmd">http实现ping工具:</div>
    62. </div>
    63. <script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.27.0/moment.min.js"></script>
    64. <script>
    65. // -----------------ping.js开始-------------------------------------
    66. /**
    67. * Creates and loads an image element by url.
    68. * @param {String} url
    69. * @return {Promise} promise that resolves to an image element or
    70. * fails to an Error.
    71. */
    72. function request_image(url) {
    73. return new Promise(function (resolve, reject) {
    74. var img = new Image();
    75. img.onload = function () { resolve(img); };
    76. img.onerror = function () { reject(url); };
    77. img.src = url + '?random-no-cache=' + Math.floor((1 + Math.random()) * 0x10000).toString(16);
    78. });
    79. }
    80. /**
    81. * Pings a url.
    82. * @param {String} url
    83. * @param {Number} multiplier - optional, factor to adjust the ping by. 0.3 works well for HTTP servers.
    84. * @return {Promise} promise that resolves to a ping (ms, float).
    85. */
    86. function ping(url, multiplier) {
    87. return new Promise(function (resolve, reject) {
    88. var start = (new Date()).getTime();
    89. var response = function () {
    90. var delta = ((new Date()).getTime() - start);
    91. delta *= (multiplier || 1);
    92. resolve(delta);
    93. };
    94. request_image(url).then(response).catch(response);
    95. // Set a timeout for max-pings, 5s.
    96. setTimeout(function () { reject(Error('Timeout')); }, 5000);
    97. });
    98. }
    99. // -----------------ping.js结束-------------------------------------
    100. let cmdHtml = '';
    101. function setSignalTip(url) {
    102. ping(url).then(function (delta) {
    103. if (navigator.onLine) {
    104. const renderSgAc = (num) => {
    105. const signalEl = document.querySelector('.signal');
    106. signalEl.querySelectorAll('.item').forEach((item) => {
    107. item.style.backgroundColor = 'gainsboro';
    108. })
    109. for (let i = 0; i < num; i++) {
    110. signalEl.querySelectorAll('.item')[i].style.backgroundColor = 'green';
    111. }
    112. }
    113. if (delta > 400) { // 网络延迟
    114. renderSgAc(1)
    115. } else if (delta > 300 && delta < 400) {// 网络不好
    116. renderSgAc(2)
    117. } else if (delta > 200 && delta <= 300) { // 网络一般
    118. renderSgAc(3)
    119. } else if (delta <= 200) { // 网络优秀
    120. renderSgAc(4)
    121. }
    122. document.querySelector('.detail').innerHTML = `<div>
    123. <div>网络延迟:${delta}毫秒</div>
    124. </div>`
    125. document.querySelector('.noSignal').style.display = 'none'
    126. const urlObj = new URL(url);
    127. const cmdEl = document.querySelector('.cmd');
    128. cmdHtml = cmdEl.innerHTML+`<div>
    129. 来自 ${urlObj.host} 的回复:
    130. <span style="width:90px; display:inline-block">耗时=${delta} </span>
    131. <span>请求时间=${moment().format('YYYY-MM-DD HH:mm:ss')}</span>
    132. </div>`;
    133. cmdEl.innerHTML = cmdHtml;
    134. cmdEl.scrollTop = cmdEl.scrollHeight;
    135. } else {
    136. const signalEl = document.querySelector('.signal');
    137. signalEl.querySelectorAll('.item').forEach((item) => {
    138. item.style.backgroundColor = 'gainsboro';
    139. })
    140. document.querySelector('.detail').innerHTML = `<div>
    141. <div>网络延迟:err毫秒</div>
    142. <div>网络错误</div>
    143. </div>`
    144. document.querySelector('.noSignal').style.display = 'block'
    145. }
    146. }).catch(function (err) {
    147. const signalEl = document.querySelector('.signal');
    148. signalEl.querySelectorAll('.item').forEach((item) => {
    149. item.style.backgroundColor = 'gainsboro';
    150. })
    151. document.querySelector('.detail').innerHTML = `<div>
    152. <div>网络延迟:err毫秒</div>
    153. <div>网络错误</div>
    154. </div>`
    155. document.querySelector('.noSignal').style.display = 'block'
    156. });
    157. }
    158. setSignalTip('服务器文件地址')
    159. setInterval(() => {
    160. setSignalTip('服务器文件地址')
    161. }, 1000)
    162. </script>
    163. </body>
    164. </html>