优雅的 跨窗口通信 与 全局页面管理 解决方案 cross-window-message 不同窗口发消息js库

🚀 优雅的 跨窗口通信 与 全局页面管理 解决方案 cross-window-message

分享一个本人开发的 跨窗口通信 与 全局页面管理


0. 特性

  1. 支持不同页面之间的 定向通信 和 广播通信
  2. 支持任意方式打开的页面,不局限于 window.open 方法
  3. 支持多个由主页面打开的子页面之间通信
  4. 支持标记和追踪各个页面的状态,方便进行全局页面管理
  5. 支持关闭子页面等多种方法调用
  6. 支持监听页面事件
  7. 页面存活检查,保证页面状态同步
  8. typescript开发,使用简单,体积小巧

1. 安装使用

1.1 npm
npm i cross-window-message
import initMessager from 'cross-window-message'; 
1.2 cdn 引入
<script src="https://cdn.jsdelivr.net/npm/cross-window-message/cross-window-message.min.js"></script>
<script>
    console.log(initMessager);
</script>

2. 使用介绍

cross-window-message 原理是基于 window.onstorage 事件以及 localStorage 进行跨页面通信

为什么不使用 window.open 配合 postMessage和onMessage事件,有以下几点原因

  1. 使用条件比较苛刻,只适用于使用 window.open 打开的页面
  2. 多个由主页面打开的子页面之间不方便通信
  3. 多个页面之间无法广播通信
  4. 无法标记各个页面状态

使用流程

进入页面时调用 initMessager 生成一个 Messager, 该方法支持传入两个可选参数,pageName 和 pageId

pageName 表示页面名称,可以有相同的页面。如果不传入则使用当前页面的 pathname

pageId 表示页面ID,每一个新页面必须是唯一的。如果不传入会生成一个默认的唯一id

import initMessager from 'cross-window-message'; 
const messager = initMessager('pageName', 'pageId');

之后各个页面之间的通信都是依赖于这个 Messager 进行

3. api

3.1 Messager ts声明
interface IMessager {
    pageId: string;
    pageName: string;
    postMessage(data: any, messageType?: number | string): void;
    postMessageToTargetId(targetPageId: string, data: any, messageType?: number | string): void;
    postMessageToTargetName(targetPageName: string, data: any, messageType?: number | string): void;
    onMessage(fn: (msgData: IMsgData) => void): () => void;
    onUnload(func: (event: BeforeUnloadEvent) => void): () => void;
    onClick(func: (event: MouseEvent) => void): () => void;
    onShow(func: (event: Event) => void): () => void;
    onHide(func: (event: Event) => void): () => void;
    method: {
        closeOtherPage(): void;
        closeOtherSamePage(): void;
        alertInTargetName(text: string | number, pageName: string): void;
        alertInTargetId(text: string | number, pageId: string): void;
        closePageByPageName(pageName: string): void;
        closePageByPageId(pageId: string): void;
        getLastOpenPage(): IPage | null;
        getLatestActivePage(): IPage | null;
        getAllPages(): IPage[];
    }
}

interface IPage {
    name: string;
    id: string;
    index: number;
    show: boolean;
}
interface IMsgData {
    data: any;
    page: IPage;
    messageType: string | number;
    messageId: string;
    targetPageId?: string;
    targetPageName?: string;
}
3.2 pageId 和 pageName

传入或生成的页面id和页面名称属性

3.3 postMessage 方法
function postMessage(data: any, messageType?: number | string): void;
import initMessager from 'cross-window-message'; 
const messager = initMessager('pageName', 'pageId');
messager.postMessage({
    text: 'Hello World!'
})

向其他所有页面(包含自己)发送数据,第二个参数表示消息类型,可以为空

3.4 postMessageToTargetId 和 postMessageToTargetName

function postMessageToTargetId(targetPageId: string, data: any, messageType?: number | string): void;
function postMessageToTargetName(targetPageName: string, data: any, messageType?: number | string): void;

这两个方法用于向指定 pageId 或者 pageName 的页面定向发送数据,其他非目标页面不会收到消息

其他用法与 postMessage 一致

3.5 onMessage
function onMessage(fn: (msgData: IMsgData) => void): () => void;

interface IMsgData {
    data: any; // postMessage 传入的data
    page: IPage; // 消息来源页面的信息
    messageType: string | number; // postMessage 传入的 messageType
    messageId: string; // 生成的唯一消息id
    targetPageId?: string; // 调用 postMessageToTargetId 时传入的 targetPageId 可以通过这个属性判断消息是否来自与 postMessageToTargetId 方法
    targetPageName?: string;  // 调用 postMessageToTargetName 时传入的 targetPageName 可以通过这个属性判断消息是否来自与 postMessageToTargetName 方法
}
interface IPage {
    name: string; // 页面的名称
    id: string; // 页面id
    index: number; // 页面打开的次序
    show: boolean; // 页面是否可见
}
import initMessager from 'cross-window-message'; 
const messager = initMessager('pageName', 'pageId');
messager.onMessage((msgData)=>{
    console.log(msgData);
})

注册一个接收消息的事件

事件回调接收的参数是一个 IMsgData 类型

3.6 页面事件
function onUnload(func: (event: BeforeUnloadEvent) => void): () => void;
function onClick(func: (event: MouseEvent) => void): () => void;
function onShow(func: (event: Event) => void): () => void;
function onHide(func: (event: Event) => void): () => void;

分别用于监听页面的 beforeunload click visibilitychange 事件

参数与原生一致

3.7 工具方法

messager.method 对象上暴露了一些工具方法

import initMessager from 'cross-window-message'; 
const messager = initMessager('pageName', 'pageId');
messager.method.closeOtherPage()
closeOtherPage(): void; // 关闭其他所有页面
closeOtherSamePage(): void; // 关闭其他所有和当前页面pageName相同的页面
alertInTargetName(text: string | number, pageName: string): void; // 在目标pageName页面alert一条消息
alertInTargetId(text: string | number, pageId: string): void; // 在目标pageId页面alert一条消息
closePageByPageName(pageName: string): void; // 关闭所有目标pageName页面
closePageByPageId(pageId: string): void; // 关闭目标pageId页面
getLastOpenPage(): IPage | null; // 获取最新打开的页面
getLatestActivePage(): IPage | null; // 获取最新的活跃页面 (触发了click或者onshow事件的页面)
getAllPages(): IPage[]; // 获取所有打开的页面
3.8 版本
import initMessager from 'cross-window-message'; 
initMessager.version;
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值