【前端實戰】使用 BroadcastChannel API 實現跨標簽頁通信

一、引言

在現代 Web 應用開發中,我們常常會遇到需要在不同瀏覽器標簽頁之間進行通信的需求。例如,在一個電商應用中,用戶在一個標簽頁中添加商品到購物車,希望在其他標簽頁中也能實時顯示購物車的更新信息。傳統的實現方式可能會依賴 localStorage 結合 storage 事件,但這種方式存在諸多限制,如性能問題、5MB 大小限制等。而 BroadcastChannel API 則為我們提供了一種更高效、更強大的跨標簽頁通信解決方案。

二、BroadcastChannel API 簡介

BroadcastChannel API 是 HTML5 新增的一個 API,用于在同源的不同瀏覽器窗口、標簽頁、iframe 等之間進行實時通信。它具有以下優點:

  1. 更高效:不依賴 storage 事件,性能更好。
  2. 無大小限制:沒有 localStorage 的 5MB 大小限制。
  3. 支持復雜數據類型:可以傳輸復雜的數據結構,如對象、數組等。
  4. 原生支持跨標簽頁通信:使用簡單,易于實現。

三、兼容性表格

瀏覽器支持版本
Chrome54+
Firefox38+
Safari10.1+
Edge17+
Opera41+

從這個表格可以看出,BroadcastChannel API 在現代主流瀏覽器中都有較好的支持,如果你不需要兼容特別舊的瀏覽器版本,那么可以放心使用。

四、實現跨標簽頁通信的代碼示例

1. 封裝跨標簽頁通信類

首先,我們創建一個 TabCommunication 類來封裝 BroadcastChannel API 的使用。

/*** 跨標簽頁通信類* 使用 BroadcastChannel API 實現* * 優點:* 1. 更高效,不依賴 storage 事件* 2. 沒有 5MB 大小限制* 3. 支持復雜數據類型* 4. 原生支持跨標簽頁通信* * @class TabCommunication*/
class TabCommunication {constructor(channelName = 'tab_comm_channel') {this.channelName = channelName;this.channel = new BroadcastChannel(channelName);this.listeners = {};this.channel.onmessage = (event) => {const { type, data } = event.data;if (this.listeners[type]) {this.listeners[type].forEach(callback => callback(data));}};}/*** 發送消息到其他標簽頁* @param {string} type 消息類型* @param {*} data 消息數據*/send(type, data) {this.channel.postMessage({ type, data });}/*** 監聽特定類型的消息* @param {string} type 消息類型* @param {function} callback 回調函數* @returns {function} 取消監聽的函數*/on(type, callback) {if (!this.listeners[type]) {this.listeners[type] = [];}this.listeners[type].push(callback);// 返回取消監聽函數return () => this.off(type, callback);}/*** 移除監聽* @param {string} type 消息類型* @param {function} callback 回調函數*/off(type, callback) {if (!this.listeners[type]) return;const index = this.listeners[type].indexOf(callback);if (index !== -1) {this.listeners[type].splice(index, 1);}if (this.listeners[type].length === 0) {delete this.listeners[type];}}/*** 關閉通信通道*/close() {this.channel.close();}
}const tabComm = new TabCommunication();
export default tabComm;

2. 消息發送頁面(sender.html)

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>消息發送者</title>
</head><body><div id="app"><button data-message="這是來自 sender.html 的消息1">發送消息1</button><button data-message="這是來自 sender.html 的消息2">發送消息2</button></div><script type="module">import tabComm from './tabCommunication.js';const app = document.getElementById('app');// 統一處理按鈕點擊app.addEventListener('click', async (e) => {if (e.target.tagName !== 'BUTTON') return;try {const message = e.target.dataset.message;await tabComm.send('message', { text: message });alert(`消息已發送: ${message}`);} catch (error) {console.error('發送消息失敗:', error);alert('發送消息失敗,請檢查控制臺');}});// 頁面關閉時關閉通信通道window.addEventListener('beforeunload', () => {tabComm.close();});</script>
</body></html>

3. 消息接收頁面(receiver.html)

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>消息接收者</title>
</head><body><div id="messageDisplay"></div><script type="module">import tabComm from './tabCommunication.js';const messageDisplay = document.getElementById('messageDisplay');const unsubscribe = tabComm.on('message', (data) => {messageDisplay.textContent = `收到消息: ${data.text}`;});// 頁面關閉時取消監聽并關閉通道window.addEventListener('beforeunload', () => {unsubscribe();tabComm.close();});</script>
</body></html>

五、代碼解釋

1. TabCommunication

  • 構造函數:初始化 BroadcastChannel 實例,并為 onmessage 事件添加處理函數,當接收到消息時,會根據消息類型調用相應的回調函數。
  • send 方法:用于向其他標簽頁發送消息,消息包含類型和數據。
  • on 方法:用于監聽特定類型的消息,將回調函數添加到對應的監聽器數組中,并返回一個取消監聽的函數。
  • off 方法:用于移除指定類型的監聽器。
  • close 方法:關閉 BroadcastChannel 實例。

2. sender.html

  • 通過按鈕點擊事件觸發消息發送,調用 tabComm.send 方法發送消息。
  • 在頁面關閉時,調用 tabComm.close 方法關閉通信通道。

3. receiver.html

  • 使用 tabComm.on 方法監聽 message 類型的消息,當接收到消息時,更新頁面顯示。
  • 在頁面關閉時,調用取消監聽函數和 tabComm.close 方法取消監聽并關閉通道。

六、總結

通過 BroadcastChannel API,我們可以輕松實現跨標簽頁的實時通信,避免了傳統方法的諸多限制。在實際開發中,如果你需要在同源的不同標簽頁之間進行數據交互,不妨考慮使用 BroadcastChannel API。同時,要注意瀏覽器的兼容性問題,確保你的目標用戶使用的瀏覽器支持該 API。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/901449.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/901449.shtml
英文地址,請注明出處:http://en.pswp.cn/news/901449.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

微信小程序 - [渲染層錯誤] Uncaught TypeError: Cannot read property ‘D‘ of undefined

問題&#xff1a;[渲染層錯誤] Uncaught TypeError: Cannot read property D of undefined 解決&#xff1a; 該錯誤可能還是小程序的渲染模式有關系&#xff0c;查看app.json中是否有如下配置&#xff0c;刪除即可&#xff0c;或者降低小程序調試基礎庫版本。

【MySQL高級】事務,存儲引擎,索引(一)

Mysql高級 DQL查詢語句 反引號 模糊查詢避免%出現在開頭,會造成索引失效 order by排序先后 表名列名都需要用${}&#xff0c;他們不能帶’’ 去重統計數量 null的運算 分組函數會自動忽略null&#xff0c;不用對null進行處理 截取子串substr&#xff08;字段&#xff0c;下標…

面試篇 - GPT-1(Generative Pre-Training 1)

GPT-1&#xff08;Generative Pre-Training 1&#xff09; ?模型結構 Transformer only-decoder&#xff1a;GPT-1模型使用了一個12層的Transformer解碼器。具體細節與標準的Transformer相同&#xff0c;但位置編碼是可訓練的。 注意力機制&#xff1a; 原始Transformer的解…

ubuntu24.04 cmake 報錯 libldap-2.5.so.0 解決辦法

apt cmake有毛病 換源重新安裝 wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | sudo apt-key add - sudo apt-add-repository "deb https://apt.kitware.com/ubuntu/ $(lsb_release -cs) main" sudo apt update sudo apt in…

ScholarCopilot:“學術副駕駛“

這里寫目錄標題 引言&#xff1a;學術寫作的痛點與 AI 的曙光ScholarCopilot 的核心武器庫&#xff1a;智能生成與精準引用智能文本生成&#xff1a;不止于“下一句”智能引用管理&#xff1a;讓引用恰到好處 揭秘背后機制&#xff1a;檢索與生成的動態協同快速上手&#xff1a…

vivo X200 Ultra前瞻系列(2):vivo X200 Ultra影像技術溝通會總結

vivo于今日(2025年4月14日)舉辦的“X系列藍圖影像技術溝通會”中,正式發布了vivo X200 Ultra,展示了其在移動影像領域的多項技術突破。以下是本次溝通會的核心內容總結: 1. 硬件革新:蔡司三焦段鏡頭與雙芯架構 蔡司三大定焦大師鏡頭: X200 Ultra采用14mm超廣角(“鷹眼”…

代碼隨想錄第17天:二叉樹

一、二叉搜索樹的最近公共祖先&#xff08;Leetcode 235&#xff09; 由于是二叉搜索樹&#xff0c;節點的值有嚴格的順序關系&#xff1a;左子樹的節點值都小于父節點&#xff0c;右子樹的節點值都大于父節點。利用這一點&#xff0c;可以在樹中更高效地找到最低公共祖先。 c…

C++中string庫常用函數超詳細解析與深度實踐

目錄 一、引言 二、基礎準備&#xff1a;頭文件與命名空間 三、string對象的創建與初始化(基礎&#xff09; 3.1 直接初始化 3.2 動態初始化&#xff08;空字符串&#xff09; 3.3 基于字符數組初始化 3.4 重復字符初始化 四、核心函數詳解 4.1 字符串長度相關 4.1.1 …

LanDiff:賦能視頻創作,語言與擴散模型的融合力量

自從 Wan 2.1 發布以來&#xff0c;AI 視頻生成領域似乎進入了一個發展瓶頸期&#xff0c;但這也讓人隱隱感到&#xff1a;“DeepSeek 時刻”即將到來&#xff01;就在前幾天&#xff0c;浙江大學與月之暗面聯合推出了一款全新的文本到視頻&#xff08;T2V&#xff09;生成模型…

【本地圖床搭建】寶塔+Docker+MinIO+PicGo+cpolar:打造本地化“黑科技”圖床方案

寫在前面&#xff1a;本博客僅作記錄學習之用&#xff0c;部分圖片來自網絡&#xff0c;如需引用請注明出處&#xff0c;同時如有侵犯您的權益&#xff0c;請聯系刪除&#xff01; 文章目錄 前言寶塔安裝DockerMinIO 安裝與設置cploar內網穿透PicGo下載與安裝typora安裝總結互動…

centos-LLM-生物信息-BioGPT-使用1

參考&#xff1a; GitHub - microsoft/BioGPT https://github.com/microsoft/BioGPT BioGPT&#xff1a;用于生物醫學文本生成和挖掘的生成式預訓練轉換器 |生物信息學簡報 |牛津學術 — BioGPT: generative pre-trained transformer for biomedical text generation and mini…

高效爬蟲:一文掌握 Crawlee 的詳細使用(web高效抓取和瀏覽器自動化庫)

更多內容請見: 爬蟲和逆向教程-專欄介紹和目錄 文章目錄 一、Crawlee概述1.1 Crawlee介紹1.2 為什么 Crawlee 是網頁抓取和爬取的首選?1.3 為什么使用 Crawlee 而不是 Scrapy1.4 Crawlee的安裝二、Crawlee的基本使用2.1 BeautifulSoupCrawler的使用方式2.2 ParselCrawler的使…

架構總覽怎么寫,才算工業級?

??系統架構文檔是整個項目最重要的起點,但很多人第一章就“寫穿了”: 不是寫得太細,就是沒有重點。想要寫出高質量、能協作、能傳承的架構文檔,這一篇會告訴你應該怎么做—— ? 架構總覽的終極目標 明確邊界、定義角色、畫清數據流 別講執行細節,別深入函數調用。 ? 架…

優先級隊列(堆二叉樹)底層的實現:

我們繼續來看我們的優先級隊列&#xff1a; 優先級隊列我們說過&#xff0c;他也是一個容器適配器&#xff0c;要依賴我們的容器來存儲數據&#xff1b; 他的第二個參數就是我們的容器&#xff0c;這個容器的默認的缺省值是vector&#xff0c;然后他的第三個參數&#xff0c;我…

GIC驅動程序分析

今天呢&#xff0c;我們就來具體的講一下GIC的驅動源碼啦&#xff0c;這個才是重點來著&#xff0c;我們來看看&#xff1a; GIC中的重要函數和結構體&#xff1a; 沿著中斷的處理流程&#xff0c;GIC涉及這4個重要部分&#xff1a; CPU從異常向量表中調用handle_arch_irq&am…

java操作redis庫,開箱即用

application.yml spring:application:name: demo#Redis相關配置redis:data:# 地址host: localhost# 端口&#xff0c;默認為6379port: 6379# 數據庫索引database: 0# 密碼password:# 連接超時時間timeout: 10slettuce:pool:# 連接池中的最小空閑連接min-idle: 0# 連接池中的最…

Cribl 通過Splunk search collector 來收集數據

今天利用Spliunk search collector 來收集數據啦:還是要先cribl 的官方文檔: Splunk Search Collector | Cribl Docs Splunk Search Collector Cribl Stream supports collecting search results from Splunk queries. The queries can be both simple and complex, as well a…

What Was the “Game Genie“ Cheat Device, and How Did It Work?

什么是“Game Genie”作弊裝置&#xff0c;它是如何工作的&#xff1f; First released in 1991, the Game Genie let players enter special codes that made video games easier or unlocked other functions. Nintendo didnt like it, but many gamers loved it. Heres wha…

位運算題目:連接連續二進制數字

文章目錄 題目標題和出處難度題目描述要求示例數據范圍 解法思路和算法代碼復雜度分析 題目 標題和出處 標題&#xff1a;連接連續二進制數字 出處&#xff1a;1680. 連接連續二進制數字 難度 5 級 題目描述 要求 給定一個整數 n \texttt{n} n&#xff0c;將 1 \text…

第十六屆藍橋杯Java b組(試題C:電池分組)

問題描述&#xff1a; 輸入格式&#xff1a; 輸出格式&#xff1a; 樣例輸入&#xff1a; 2 3 1 2 3 4 1 2 3 4 樣例輸出: YES NO 說明/提示 評測用例規模與約定 對于 30% 的評測用例&#xff0c;1≤T≤10&#xff0c;2≤N≤100&#xff0c;1≤Ai?≤10^3。對于 100…