亚洲乱色熟女一区二区三区丝袜,天堂√中文最新版在线,亚洲精品乱码久久久久久蜜桃图片,香蕉久久久久久av成人,欧美丰满熟妇bbb久久久

LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

瀏覽器跨 Tab 窗口通信原理及應(yīng)用實(shí)踐

freeflydom
2023年11月28日 15:0 本文熱度 1779

最近,相信大家一定被這么個(gè)動(dòng)效給刷屏了:

以至于,基于這個(gè)效果的二次創(chuàng)作層出不窮,眼花繚亂。

基于跨窗口通信的彈彈球:

基于跨窗口通信的 Flippy Bird:

我也嘗試制作了一個(gè)跨 Tab 窗口的 CSS 動(dòng)畫聯(lián)動(dòng),效果如下:

代碼不多,核心代碼 200 行,感興趣的可以戳這里:Github - broadcastAnimation

當(dāng)然,本文的核心不是去一一剖析上面的效果具體的實(shí)現(xiàn)方式,而是講講其中比較關(guān)鍵的一個(gè)技術(shù)點(diǎn):

而是應(yīng)用如何在多窗口下進(jìn)行互相通信。

所謂多窗口下進(jìn)行互相通信,是指在瀏覽器中,不同窗口(包括不同標(biāo)簽頁(yè)、不同瀏覽器窗口甚至不同瀏覽器實(shí)例)之間進(jìn)行數(shù)據(jù)傳輸和通信的能力。

當(dāng)然,本文我們探討的是純前端的跨 Tab 頁(yè)面通信,在非純前端的方式下,我們可以借助諸如 Web Socket 等方式,藉由后端這個(gè)中間載體,進(jìn)行跨頁(yè)面通信。

因此,本文我們更多的重心將放在,如何基于純前端技術(shù),實(shí)現(xiàn)多窗口下進(jìn)行互相通信。

為了實(shí)現(xiàn)跨窗口通信,它應(yīng)該需要具備以下能力:

  1. 數(shù)據(jù)傳輸能力:能夠?qū)?shù)據(jù)從一個(gè)窗口發(fā)送到另一個(gè)窗口,以及接收來(lái)自其他窗口的數(shù)據(jù)。

  2. 實(shí)時(shí)性:能夠?qū)崿F(xiàn)實(shí)時(shí)或近實(shí)時(shí)的數(shù)據(jù)傳輸,以便及時(shí)更新不同窗口的內(nèi)容。

  3. 安全性:確保通信過(guò)程中的數(shù)據(jù)安全,防止惡意竊取或篡改通信數(shù)據(jù)。當(dāng)然,這個(gè)不是本文討論的重點(diǎn),但是是實(shí)際應(yīng)用中不應(yīng)該忽視的一個(gè)重點(diǎn)。

方式一:Broadcast Channel()

Broadcast Channel 是一個(gè)較新的 Web API,用于在不同的瀏覽器窗口、標(biāo)簽頁(yè)或框架之間實(shí)現(xiàn)跨窗口通信。它基于發(fā)布-訂閱模式,允許一個(gè)窗口發(fā)送消息,并由其他窗口接收。

其核心步驟如下:

  1. 創(chuàng)建一個(gè) BroadcastChannel 對(duì)象:在發(fā)送和接收消息之前,首先需要在每個(gè)窗口中創(chuàng)建一個(gè) BroadcastChannel 對(duì)象,使用相同的頻道名稱進(jìn)行初始化。

  2. 發(fā)送消息:通過(guò) BroadcastChannel 對(duì)象的 postMessage() 方法,可以向頻道中的所有窗口發(fā)送消息。

  3. 接收消息:通過(guò)監(jiān)聽 BroadcastChannel 對(duì)象的 message 事件,可以在窗口中接收到來(lái)自其他窗口發(fā)送的消息。

同時(shí),Broadcast Channel 遵循瀏覽器的同源策略。這意味著只有在同一個(gè)協(xié)議、主機(jī)和端口下的窗口才能正常進(jìn)行通信。如果窗口不滿足同源策略,將無(wú)法互相發(fā)送和接收消息。

因?yàn)橛型聪拗?,我們需要起一個(gè)服務(wù),這里我基于 Vite 快速起了一個(gè) Vue 項(xiàng)目,簡(jiǎn)單的基于 .vue 文件下進(jìn)行一個(gè)演示。

其核心代碼非常簡(jiǎn)單:


<template>

  <div id="j-main">

    // ...  

  </div>

</template>


<script>

import { onMounted } from 'vue';


export default {

  setup() {

    function createBroadcastChannel() {

      broadcastChannel = new BroadcastChannel('broadcast');

      broadcastChannel.onmessage = handleMessage;

    }


    function sendMessage(data) {

      broadcastChannel.postMessage(data);

    }


    function handleMessage(event) {

        console.log('接收到 event', event);

        // TODO: 處理接收到信息后的邏輯

    }


    function resizeEventBind() {

      window.addEventListener('resize', () => {

         const pos = getCurPos();

         sendMessage(pos);

       });

    }


    // 計(jì)算當(dāng)前元素距離顯示器窗口右上角的距離

    function getCurPos() {

      const barHeight = window.outerHeight - window.innerHeight;

      const element = document.getElementById('j-main');

      const rect = element.getBoundingClientRect();


      // 獲取元素相對(duì)于屏幕左上角的 X 和 Y 坐標(biāo)

      const x = rect.left + window.screenX; // 元素左邊緣相對(duì)于屏幕左邊緣的距離

      const y = rect.top + window.screenY + barHeight;// 元素頂部邊緣相對(duì)于屏幕頂部邊緣的距離


      return [x, y];

    }

    

    onMounted(() => {

      createBroadcastChannel();

      resizeEventBind();

    });


    return {};

  }

};

</script>


<style lang="scss"></style>

這里,我們的核心邏輯在于:

  • createBroadcastChannel() 函數(shù)用于創(chuàng)建一個(gè) BroadcastChannel 對(duì)象,并設(shè)置消息處理函數(shù)。

  • sendMessage(data) 函數(shù)用于向 BroadcastChannel 發(fā)送消息。

  • handleMessage(event) 函數(shù)用于處理接收到的消息。

  • resizeEventBind() 函數(shù)用于監(jiān)聽窗口大小變化事件,并在事件發(fā)生時(shí)獲取當(dāng)前元素的位置信息,并通過(guò) sendMessage() 函數(shù)發(fā)送位置信息到 BroadcastChannel。

  • getCurPos() 函數(shù)用于計(jì)算當(dāng)前元素相對(duì)于顯示器窗口右上角的距離。

在 onMounted() 生命周期鉤子中,調(diào)用了 createBroadcastChannel() 和 resizeEventBind() 函數(shù),用于在組件掛載后執(zhí)行相關(guān)的初始化操作。

這樣,當(dāng)我們同時(shí)打開兩個(gè)窗口,移動(dòng)其中一個(gè)窗口,就可以向另外一個(gè)窗口發(fā)生當(dāng)前窗口希望傳遞過(guò)去的信息,在本例子中就是 #j-main 元素距離顯示器右上角的距離。

假設(shè) #j-main 只是一個(gè)在瀏覽器正中心矩形,我們同時(shí)打開兩邊的控制臺(tái),看看會(huì)發(fā)生什么:

可以看到,如果我們同時(shí)打開兩個(gè)一個(gè)的頁(yè)面,當(dāng)觸發(fā)右邊頁(yè)面的 Resize,左邊的頁(yè)面會(huì)收到基于 broadcastChannel.onmessage = handleMessage 接收到的信息,反之同理。

而一個(gè)完整的 Event 信息如下:

譬如,傳遞過(guò)來(lái)的信息放在 data 屬性內(nèi)、同時(shí)也可以獲取當(dāng)前的的 Broadcast Name 等。

基于 BroadcastChannel,就可以實(shí)現(xiàn)每個(gè) Tab 內(nèi)的核心信息互傳, 可以得知當(dāng)前在線設(shè)備數(shù),再基于這些信息去完成我們想要的動(dòng)畫、交互等效果。

這里的核心點(diǎn),還是:

  1. 數(shù)據(jù)向其他 Tab 頁(yè)面?zhèn)鬟f的能力

  2. Tab 頁(yè)面接受其他頁(yè)面?zhèn)鬟f過(guò)來(lái)的數(shù)據(jù)的能力

其本質(zhì)就是一個(gè)數(shù)據(jù)共享池子。

方式二:SharedWorker API

好,介紹完 Broadcast Channel(),我們?cè)賮?lái)看看 SharedWorker API。

SharedWorkerAPI 是 HTML5 中提供的一種多線程解決方案,它可以在多個(gè)瀏覽器 TAB 頁(yè)面之間共享一個(gè)后臺(tái)線程,從而實(shí)現(xiàn)跨頁(yè)面通信。

與其他 Worker 不同的是,SharedWorker 可以被多個(gè)瀏覽器 TAB 頁(yè)面共享,且可以在同一域名下的不同頁(yè)面之間建立連接。這意味著,多個(gè)頁(yè)面可以通過(guò) SharedWorker 實(shí)例之間的消息傳遞,實(shí)現(xiàn)跨 TAB 頁(yè)面的通信。

它的實(shí)現(xiàn)與上面的 Broadcast Channel 非常類似,我們來(lái)看一看實(shí)際的代碼:

<template>

  <div id="j-main">

    // ...  

  </div>

</template>


<script>

import { onMounted } from 'vue';


export default {

  setup() {

    // 創(chuàng)建一個(gè) SharedWorker 對(duì)象

    let worker;

    

    function initWorker() {

      // 創(chuàng)建一個(gè) SharedWorker 對(duì)象

      worker = new SharedWorker('/shared-worker.js', 'tabWorker');


      // 監(jiān)聽消息事件

      worker.port.onmessage = function (event) {

        console.log('接收到 event', event);

        handleMessage(event);

      };

    }

    

    function handleMessage(data) {

      // TODO: 處理接收到信息后的邏輯

    }


    function sendMessage(data) {

      // 發(fā)送消息

      worker.port.postMessage(data);

    }


    function resizeEventBind() {

      window.addEventListener('resize', () => {

        const pos = getCurPos();

        sendMessage(pos);

      });

    }


    function getCurPos() {

      const barHeight = window.outerHeight - window.innerHeight;

      const element = document.getElementById('j-main');

      const rect = element.getBoundingClientRect();


      // 獲取元素相對(duì)于屏幕左上角的 X 和 Y 坐標(biāo)

      const x = rect.left + window.screenX; // 元素左邊緣相對(duì)于屏幕左邊緣的距離

      const y = rect.top + window.screenY + barHeight;// 元素頂部邊緣相對(duì)于屏幕頂部邊緣的距離


      return [x, y];

    }

    

    onMounted(() => {

      initWorker();

      resizeEventBind();

    });


    return {};

  }

};

</script>


<style></style>

簡(jiǎn)單描述一下,上面也說(shuō)了,跨 Tab 頁(yè)通信的核心在于數(shù)據(jù)向外的發(fā)送與接收的能力:

  1. initWorker() 方法中,使用 worker = newSharedWorker('/shared-worker.js', 'tabWorker') 創(chuàng)建了一個(gè) SharedWorker , 后面每一個(gè)被打開的同域?yàn)g覽器 TAB 頁(yè)面,都是共享這個(gè) Worker 線程,從而實(shí)現(xiàn)跨頁(yè)面通信

  2. 基于 worker.port.postMessage(data)實(shí)現(xiàn)數(shù)據(jù)的傳輸

  3. 基于 worker.port.onmessage = function() {} 實(shí)現(xiàn)傳輸數(shù)據(jù)的監(jiān)聽

當(dāng)然,上面有引入一個(gè) /shared-worker.js,這個(gè)是需要額外定義的,一個(gè)極簡(jiǎn)版本的代碼如下:

//shared-worker.js

const connections = [];


onconnect = function (event) {

  var port = event.ports[0];

  connections.push(port);


  port.onmessage = function (event) {

    // 接收到消息時(shí),向所有連接發(fā)送該消息

    connections.forEach(function (conn) {

      if (conn !== port) {

        conn.postMessage(event.data);

      }

    });

  };


  port.start();

};

簡(jiǎn)單解析一下,下面對(duì)其進(jìn)行解析:

  1. 上面的代碼中,定義了一個(gè)數(shù)組 connections,用于存儲(chǔ)與 SharedWorker 建立連接的各個(gè)頁(yè)面的端口對(duì)象;

  2. onconnect 是事件處理程序,當(dāng)有新的連接建立時(shí)會(huì)觸發(fā)該事件;

  3. 在 onconnect 函數(shù)中,通過(guò) event.ports[0] 獲取到與 SharedWorker 建立的連接的第一個(gè)端口對(duì)象,并將其添加到 connections 數(shù)組中,表示該頁(yè)面與共享 Worker 建立了連接。

  4. 在連接建立后,為每個(gè)端口對(duì)象設(shè)置了 onmessage 事件處理程序。當(dāng)端口對(duì)象接收到消息時(shí),會(huì)觸發(fā)該事件處理程序。

  5. 在 onmessage 事件處理程序中,通過(guò)遍歷 connections 數(shù)組,將消息發(fā)送給除當(dāng)前連接端口對(duì)象之外的所有連接。這樣,消息就可以在不同的瀏覽器 TAB 頁(yè)面之間傳遞。

  6. 最后,通過(guò)調(diào)用 port.start() 啟動(dòng)端口對(duì)象,使其開始接收消息。

總而言之,shared-worker.js 腳本創(chuàng)建了一個(gè)共享 Worker 實(shí)例,它可以接收來(lái)自不同頁(yè)面的連接請(qǐng)求,并將接收到的消息發(fā)送給其他連接的頁(yè)面。通過(guò)使用 SharedWorker API,實(shí)現(xiàn)跨 TAB 頁(yè)面之間的通信和數(shù)據(jù)共享

同理,我們來(lái)看看基于 Worker 的數(shù)據(jù)傳輸效果,同樣是簡(jiǎn)化 DEMO,當(dāng) Resize 窗口時(shí),向另外一個(gè)窗口發(fā)送當(dāng)前窗口下 #j-main 元素的坐標(biāo):

可以看到,如果我們同時(shí)打開兩個(gè)一個(gè)的頁(yè)面,當(dāng)觸發(fā)右邊頁(yè)面的 Resize,左邊的頁(yè)面會(huì)利用 worker.port.onmessage = function() {} 收到基于 worker.port.postMessage(data) 發(fā)送的信息,反之同理。

而一個(gè)完整的 Event 信息如下:

可以看到,在 SharedWorker 方式中,傳輸數(shù)據(jù)與 Broadcast Channel 是一樣的,都是利用 Message Event。簡(jiǎn)單對(duì)比一下:

  1. SharedWorker 通過(guò)在多個(gè)Tab頁(yè)面之間共享相同的 Worker 實(shí)例,方便地共享數(shù)據(jù)和狀態(tài),SharedWorker 需要多定義一個(gè) shared-worker.js;

  2. Broadcast Channel 通過(guò)向所有訂閱同一頻道的 Tab 頁(yè)面廣播消息,實(shí)現(xiàn)廣播式的通信。

兼容性方面,到今天(2023-11-26),broadcast Channel 看著是兼容性更好的方式:

另外,需要注意的是,兩個(gè)方法都使用了 postMessage 方法。window.postMessage() 方法可以安全地實(shí)現(xiàn)跨源通信。并且,本質(zhì)上而言,單獨(dú)使用 postMessage 就可以實(shí)現(xiàn)跨 Tab 通信。

但是,單獨(dú)使用 postMessage 適合簡(jiǎn)單的點(diǎn)對(duì)點(diǎn)通信。在更復(fù)雜的場(chǎng)景中,Broadcast Channel 和 SharedWorker 提供更強(qiáng)大的機(jī)制,可簡(jiǎn)化通信邏輯,有更廣泛的通信范圍和生命周期管理。Broadcast Channel 的通信范圍是所有訂閱該頻道的窗口,而 SharedWorker 可在多個(gè)窗口之間共享狀態(tài)和通信。

方式三:localStorage/sessionStorage

OK,最后一種跨 Tab 窗口通信的方式是利用 localStorage 、sessionStorage 本地化存儲(chǔ) API 以及的 storage 事件。

與上面 Broadcast Channel、SharedWorker 稍微不同的地方在于:

  1. localStorage 方式,利用了本地瀏覽器存儲(chǔ),實(shí)現(xiàn)了同域下的數(shù)據(jù)共享;

  2. localStorage 方式,基于 window.addEventListener('storage',function(event) {})事件實(shí)現(xiàn)了 localStore 變化時(shí)候的數(shù)據(jù)監(jiān)聽;

簡(jiǎn)單看看代碼:

<template>

  <div id="j-main">

    // ...  

  </div>

</template>


<script>

import { ref, reactive, computed, onMounted } from 'vue';


export default {

  setup() {

    function initLocalStorage() {

      let tabArray = JSON.parse(localStorage.getItem('tab_array'));

      if (!tabArray) {

        const tabIndex = 1;

        id = tabIndex;

        localStorage.setItem('tab_array', JSON.stringify([tabIndex]));

      } else {

        const tabIndex = tabArray[tabArray.length - 1] + 1;

        id = tabIndex;

        const newTabArray = [...tabArray, tabIndex];

        localStorage.setItem('tab_array', JSON.stringify(newTabArray));

      }

    }


    function setLocalStorage(data) {

      localStorage.setItem(`tab_index_${id}`, JSON.stringify(data));

    }


    function handleMessage(data) {

      const rArray = JSON.parse(data);

      remoteX.value = rArray[0];

      remoteY.value = rArray[1];

    }


    function resizeEventBind() {

      window.addEventListener('resize', () => {

         const pos = getCurPos();

         setLocalStorage(pos);

      });

 

      window.addEventListener('storage', (event) => {

        console.log('localStorage 變化了!', event);

        console.log('鍵名:', event.key);

        console.log('變化前的值:', event.oldValue);

        console.log('變化后的值:', event.newValue);

        handleMessage(event.newValue);

      });

    }


    function getCurPos() {

      const barHeight = window.outerHeight - window.innerHeight;

      const element = document.getElementById('j-main');

      const rect = element.getBoundingClientRect();


      // 獲取元素相對(duì)于屏幕左上角的 X 和 Y 坐標(biāo)

      const x = rect.left + window.screenX; // 元素左邊緣相對(duì)于屏幕左邊緣的距離

      const y = rect.top + window.screenY + barHeight;// 元素頂部邊緣相對(duì)于屏幕頂部邊緣的距離


      return [x, y];

    }

    

    onMounted(() => {

      initLocalStorage();

      resizeEventBind();

    });


    return {};

  }

};

</script>


<style></style>

同樣的簡(jiǎn)單解析一下:

  1. 每次頁(yè)面初始化時(shí),都會(huì)首先有一個(gè) initLocalStorage 過(guò)程,用于給當(dāng)前頁(yè)面一個(gè)唯一 ID 標(biāo)識(shí),并且存入 localStorage 中

  2. 每次頁(yè)面 resize,將當(dāng)前頁(yè)面元素 #j-main 的坐標(biāo)值,通過(guò) ID 標(biāo)識(shí)當(dāng) Key,存入 localStorage 中

  3. 其他頁(yè)面,通過(guò) window.addEventListener('storage', (event)=> {}) 監(jiān)聽 localStorage 的變化

交互傳輸結(jié)果,與上述兩個(gè)動(dòng)圖是一致的,就不額外貼圖了,但是基于 storage 事件傳輸?shù)闹涤悬c(diǎn)不一樣,我們展開看看:

我們通過(guò) window.addEventListener('storage', (event)=>{}) ,可以拿到此次變化的 localStorage key 是什么,前值 oldValue 與 newValue 等等。

當(dāng)然,由于 localStorage 存儲(chǔ)過(guò)程只能是字符串,在讀取的時(shí)候需要利用 JSON.stringify 和 JSON.parse 額外處理一層,調(diào)試的時(shí)候需要注意。

雖然看起來(lái)這種方式最不優(yōu)雅,但是結(jié)合兼容性一起看, localstorage 反而是兼容性最好的方式。在數(shù)據(jù)量較小的時(shí)候,性能相差不會(huì)太大,反而可能是更好的選擇。

我基于上面三種方式:Broadcast Channel、SharedWorker 與 localStorage,都實(shí)現(xiàn)了一遍下面這個(gè)跨 Tab 頁(yè)的 CSS 聯(lián)動(dòng)動(dòng)畫:

三種方式的代碼都不多,感興趣的可以戳這里:Github - broadcastAnimation

實(shí)際應(yīng)用思考

當(dāng)然,上面的實(shí)現(xiàn)其實(shí)有很大一個(gè)瑕疵。

那就是我們只顧著實(shí)現(xiàn)通信,沒(méi)有考慮實(shí)際應(yīng)用中的一些實(shí)際問(wèn)題:

  1. 如何確定何時(shí)開始通信?

  2. Tab 頁(yè)頻繁的開關(guān),如何知道當(dāng)前還有多少頁(yè)面處于打開狀態(tài)?

基于實(shí)際應(yīng)用,我們需要基于上述 3 種方式,進(jìn)一步細(xì)化方案。

上面,為了方便演示,每次傳輸數(shù)據(jù)時(shí),只傳輸動(dòng)畫需要的數(shù)據(jù)。而實(shí)際應(yīng)用,我們可以需要細(xì)化整個(gè)傳輸數(shù)據(jù),設(shè)定合理的協(xié)議。譬如:

{    // 傳輸狀態(tài):
    // 1 - 首次傳輸
    // 2 - 正常通信
    // 3 - 頁(yè)面關(guān)閉
    status: 1 | 2 | 3,    
    data: {}
}

接收方需要基于收到信息所展示的不同的狀態(tài),做出不同的反饋。

當(dāng)然,還有一個(gè)問(wèn)題,我們?nèi)绾沃理?yè)面被關(guān)閉了?基于組件的 onUnmounted 發(fā)送當(dāng)前頁(yè)面關(guān)閉的信息或者基于 window 對(duì)象的 beforeunload 事件發(fā)送當(dāng)前頁(yè)面關(guān)閉的信息?

這些信息都有可能因?yàn)?Tab 頁(yè)面失活,導(dǎo)致關(guān)閉的信息無(wú)法正常被發(fā)送出去。所以,實(shí)際應(yīng)用中,我們經(jīng)常用的一項(xiàng)技術(shù)是心跳上報(bào)/心跳廣播,一旦建立連接后,間隔 X 秒發(fā)送一次心跳廣播,告訴其他接收端,我還在線。一旦超過(guò)某個(gè)時(shí)間閾值沒(méi)有收到心跳上報(bào),各個(gè)訂閱方可以認(rèn)為該設(shè)備已經(jīng)下線。

總而言之,跨 Tab 窗口通信應(yīng)用在實(shí)際應(yīng)用的過(guò)程中,我們需要思考更多可能隱藏的問(wèn)題。

跨 Tab 窗口通信應(yīng)用場(chǎng)景

當(dāng)然,除了最近大火的跨 Tab 動(dòng)畫應(yīng)用場(chǎng)景,實(shí)際業(yè)務(wù)中,還有許多場(chǎng)景是它可以發(fā)揮作用的。這些場(chǎng)景利用了跨 Tab 通信技術(shù),增強(qiáng)了用戶體驗(yàn)并提供了更豐富的功能。

以下是一些常見(jiàn)的應(yīng)用場(chǎng)景:

  1. 實(shí)時(shí)協(xié)作:多個(gè)用戶可以在不同的 Tab 頁(yè)上進(jìn)行實(shí)時(shí)協(xié)作,比如編輯文檔、共享白板、協(xié)同編輯等。通過(guò)跨Tab通信,可以實(shí)現(xiàn)實(shí)時(shí)更新和同步操作,提高協(xié)作效率。

譬如這個(gè):

  1. 多標(biāo)簽頁(yè)數(shù)據(jù)同步:當(dāng)用戶在一個(gè)標(biāo)簽頁(yè)上進(jìn)行了操作,希望其他標(biāo)簽頁(yè)上的數(shù)據(jù)也能實(shí)時(shí)更新時(shí),可以使用跨 Tab 通信來(lái)實(shí)現(xiàn)數(shù)據(jù)同步,保持用戶在不同標(biāo)簽頁(yè)上看到的數(shù)據(jù)一致性。

  2. 跨標(biāo)簽頁(yè)通知:在某些場(chǎng)景下,需要向用戶發(fā)送通知或提醒,即使用戶不在當(dāng)前標(biāo)簽頁(yè)上也能及時(shí)收到。通過(guò)跨 Tab 通信,可以實(shí)現(xiàn)跨頁(yè)面的消息傳遞,向用戶發(fā)送通知或提醒。

  3. 多標(biāo)簽頁(yè)狀態(tài)同步:有些應(yīng)用可能需要在不同標(biāo)簽頁(yè)之間同步用戶的狀態(tài)信息,例如登錄狀態(tài)、購(gòu)物車內(nèi)容等。通過(guò)跨 Tab 通信,可以確保用戶在不同標(biāo)簽頁(yè)上看到的狀態(tài)信息保持一致。

  4. 頁(yè)面間數(shù)據(jù)傳輸:有時(shí)候用戶需要從一個(gè)頁(yè)面跳轉(zhuǎn)到另一個(gè)頁(yè)面,并攜帶一些數(shù)據(jù),通過(guò)跨Tab通信可以在頁(yè)面之間傳遞數(shù)據(jù),實(shí)現(xiàn)數(shù)據(jù)的共享和傳遞。

舉幾個(gè)實(shí)際的例子:

  1. 某系統(tǒng)是一個(gè)國(guó)際化電商的倉(cāng)庫(kù)管理系統(tǒng),系統(tǒng)能切換到全球各地不同的倉(cāng)庫(kù)進(jìn)行數(shù)據(jù)操作,當(dāng)用戶打開了頁(yè)面后,又新開了一個(gè) Tab 頁(yè)面,并且切換到另外一個(gè)倉(cāng)庫(kù)進(jìn)行操作。當(dāng)用戶重新回到第一個(gè)打開的頁(yè)面時(shí),為了防止用戶錯(cuò)誤操作數(shù)據(jù)(前端界面是一致的,可能忘記了自己切換過(guò)倉(cāng)庫(kù)),通過(guò)彈窗提醒用戶你已經(jīng)切換過(guò)倉(cāng)庫(kù);

  2. 某音樂(lè)播放器 PC 頁(yè)面,在列表頁(yè)面進(jìn)行歌曲播放點(diǎn)擊,如果當(dāng)前沒(méi)有音樂(lè)播放詳情頁(yè),則打開一個(gè)新的播放詳情頁(yè)。但是,如果頁(yè)面已經(jīng)存在一個(gè)音樂(lè)播放詳情頁(yè),則不會(huì)打開新的音樂(lè)播放詳情頁(yè),而是直接使用已經(jīng)存在的播放詳情頁(yè)面;

  3. 系統(tǒng)有與列表頁(yè)與內(nèi)容頁(yè),在內(nèi)容頁(yè)點(diǎn)擊已閱,如果用戶同時(shí)打開了上級(jí)列表頁(yè),要取消列表頁(yè)關(guān)于該內(nèi)容頁(yè)的未讀的提示;

總之,跨 Tab 窗口通信在實(shí)時(shí)協(xié)作、數(shù)據(jù)同步、通知提醒等方面都能發(fā)揮重要作用,為用戶提供更流暢、便捷的交互體驗(yàn)。

最后

本文只羅列了 3 種較為常見(jiàn),適用性強(qiáng)的方式。除去本文羅列的方式,肯定還有其他方式能夠?qū)崿F(xiàn)跨 Tab 通信。

譬如,基于 Window: opener property 配合 postMessage 也可以實(shí)現(xiàn)跨 Tab 窗口通信,但是這種通信僅僅適用于當(dāng)前窗口以及通過(guò)當(dāng)前窗口新開的窗口之間的通信。

更多有意思的方式,期待大家的補(bǔ)充與探索。

好了,本文到此結(jié)束,希望對(duì)你有幫助 😃

作者:ChokCoco

來(lái)源鏈接:https://www.cnblogs.com/coco1s/p/17861360.html


該文章在 2023/11/28 15:03:45 編輯過(guò)
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國(guó)內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉(cāng)儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購(gòu)管理,倉(cāng)儲(chǔ)管理,倉(cāng)庫(kù)管理,保質(zhì)期管理,貨位管理,庫(kù)位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved