網(wǎng)上關(guān)于serviceWorker一般是用于做PWA的,這里介紹的不是這個(gè),如需了解,自行百度
原理:
serviceWorker是一個(gè)獨(dú)立于頁(yè)面的,瀏覽器級(jí)別的線程
serviceWorker線程可以與頁(yè)面間通過(guò)addEventListener('message',postMessage進(jìn)行通信
serviceWorker線程中可以獲取到所有被此線程控制的瀏覽器窗口 self.clients.matchAll()
代碼解析
- 首先頁(yè)面中初始時(shí)要初始化
serviceWorker:
navigator.serviceWorker
.register('serviceWorker.js', {
scope: '/',
})
.then(function(registration) {
if (config && config.onRegister) {
config.onRegister(registration)
}
...
- 每個(gè)頁(yè)面進(jìn)入時(shí),通知
serviceWorker有新頁(yè)面打開了,并監(jiān)聽serviceWorker的信息。
頁(yè)面代碼:
navigator.serviceWorker.controller.postMessage({
type: 'closeOtherClient',
})
if (event.data.oprType && event.data.oprType === 'close') {
disconnectCBS.forEach(cb => cb())
}
-
serviceWorker.js代碼
serviceWorker收到新窗口打開信號(hào)后,去通知其他所有頁(yè)面執(zhí)行關(guān)閉代碼(比如頁(yè)面上彈框提示用戶,您的賬號(hào)已在別處登陸)
this.addEventListener('message', function(event) {
const senderId = event.source ? event.source.id : 'unknow'
if (event.data.type === 'closeOtherClient') {
self.clients.matchAll().then(function(clients) {
if (clients && clients.length) {
clients.forEach(function(client) {
if (senderId !== client.id) {
client.postMessage({
oprType: 'close'
})
}
})
}
})
}
})