好的斷網處理會讓人很溫馨: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
努力成爲優秀前端工程師!