好的断网处理会让人很温馨:lol的断线重连,王者荣耀的断线重连 能够确保游戏的继续进行css
坏的断网处理甚至不处理会出bug:好比我手上的项目就出了个bug 业务人员表示很是苦恼html
网络问题一直是一个很值得关注的问题。前端
好比在慢网状况下,增长loading避免重复发请求,使用promise顺序处理请求的返回结果,或者是增长一些友好的上传进度提示等等。vue
那么你们有没有想过断网状况下该怎么作呢?好比说网络正常->断网->网络正常。git
其实我一直也没想过,直到组里的测试测出一个断网致使的bug,让我意识到重度依赖网络请求的前端,在断网状况下可能会出现严重的bug。github
所以我将在这里记录一下本身对系统断网状况下的处理,一方面避免bug产生,一方面保证用户及时在应用内知道网络已经断开链接web
断网处理项目实战segmentfault
为了构建一个 “断网(offline)可用”的web应用,你须要知道应用在何时是断网(offline)的。
不单单要知道何时断网,更要知道何时网络恢复正常(online)。
能够分解陈本下面两种常见状况:promise
一般能够经过online/offline事件去作这个事情。浏览器
navigator.onLine
能够经过network的online选项切换为offline,打印navigator.onLine验证。
当浏览器不能链接到网络时,这个属性会更新。规范中是这样定义的:
The navigator.onLine attribute must return false if the user agent will not contact the network when the user follows links or when a script requests a remote page (or knows that such an attempt would fail)...
浏览器有两个事件:"online" 和 "offline".
这两个事件会在浏览器在online mode和offline mode之间切换时,由页面的<body>
发射出去。
事件会按照如下顺序冒泡:document.body -> document -> window。
事件是不能去取消的(开发者在代码上不能手动变为online或者offline,开发时使用开发者工具能够)。
最最建议window+addEventListener的组合。
<body ononline="onlineCb" onoffline="offlineCb"></body>
<div id="status"></div> <div id="log"></div>
window.addEventListener('load', function() { var status = document.getElementById("status"); var log = document.getElementById("log"); function updateOnlineStatus(event) { var condition = navigator.onLine ? "online" : "offline"; status.innerHTML = condition.toUpperCase(); log.insertAdjacentHTML("beforeend", "Event: " + event.type + "; Status: " + condition); } window.addEventListener('online', updateOnlineStatus); window.addEventListener('offline', updateOnlineStatus); });
其中insertAdjacentHTML是在标签节点的邻近位置插入,能够查阅:DOM进阶之insertAdjacentHTML
基于vue以及iView的Spin,Notice组件封装出离线处理组件,在须要到的页面引入便可。
只要作到断网提醒+遮罩,上线提醒-遮罩便可。
<OfflineHandle :offlineTitle = "断网处理标题" :desc="断网处理描述" :onlineTitle="连网提醒" > </OfflineHandle>
<!--OfflineHandle.vue--> <template> <div v-if="spin" class="offline-mark"> <Spin size="large" fix> <h2>{{offlineTitle}}</h2> <p>{{desc}}</p> </Spin> </div> </template> <script> export default { name: 'offline-handle', props: { offlineTitle: { type: String, default: '网络已断开,请检查网络链接。', }, onlineTitle: { type: String, default: '网络已链接', }, desc: { type: String, default: '', }, duration: { type: Number, default: 4.5, }, }, data() { return { spin: false, }; }, mounted() { window.addEventListener('offline', this.eventHandle); window.addEventListener('online', this.eventHandle); }, beforeDestroy() { window.removeEventListener('offline', this.eventHandle); window.removeEventListener('online', this.eventHandle); }, methods: { eventHandle(event) { const type = event.type === 'offline' ? 'error' : 'success'; this.$Notice[type]({ title: type === 'error' ? this.offlineTitle : this.onlineTitle, desc: type === 'error' ? this.desc : '', duration: this.duration, }); setTimeout(() => { this.spin = event.type === 'offline'; }, 1500); }, }, }; </script> <style lang="scss" scoped> .offline-mark { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; z-index: 9999; transition: position 2s; } /deep/.ivu-spin-fix { text-align: left; font-size: 20px; h2 { color: rgba(0, 0, 0, 0.8); } p { margin-top: 20px; color: red; font-weight: bold; } } </style>
手上的项目只运行在Chrome浏览器,只有为window设置offline和online才生效。
运行环境:"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36
参考资料:
期待和你们交流,共同进步,欢迎你们加入我建立的与前端开发密切相关的技术讨论小组:
- SegmentFault技术圈:ES新规范语法糖
- SegmentFault专栏:趁你还年轻,作个优秀的前端工程师
- 知乎专栏:趁你还年轻,作个优秀的前端工程师
- Github博客: 趁你还年轻233的我的博客
- 前端开发QQ群:660634678
- 微信公众号: 生活在浏览器里的咱们 / excellent_developers
努力成为优秀前端工程师!