npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

cross-window-message

v1.0.6

Published

Elegant cross-window communication and global page management solution

Downloads

9

Readme

cross-window-message

English | 使用实例 | 更新日志 | 反馈 | Gitee



0. 特性

  1. 支持不同页面之间的 定向通信 和 广播通信
  2. 支持任意方式打开的页面,不局限于 window.open 方法
  3. 支持多个由主页面打开的子页面之间通信
  4. 支持标记和追踪各个页面的状态,方便进行全局页面管理
  5. 支持关闭子页面等多种方法调用
  6. 支持监听页面事件
  7. 页面存活检查,保证页面状态同步
  8. 支持页面携带数据和选择sessionStorage作为存储源
  9. 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, 该方法支持传入一个可选参数 option,其中的所有属性都是可选的,数据结构如下:

interface IOptions {
    pageName?: string;
    pageId?: string;
    data?: IJson;
    useSessionStorage?: boolean;
}
  1. pageName 表示页面名称,可以有相同的页面。如果不传入则使用当前页面的 pathname
  2. pageId 表示页面ID,每一个新页面必须是唯一的。如果不传入会生成一个默认的唯一id
  3. 当前页面携带的数据,会写入storage中
  4. 是否使用 sessionStorage 存储状态,默认是使用 localStorage,这个参数需要所有页面保持一致
import initMessager from 'cross-window-message'; 
const messager = initMessager({
    pageName: 'xxx'
});

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

3. api

3.1 initMessager

调用 initMessager 生成一个 Messager,该方法传入可选的 option参数

import initMessager from 'cross-window-message'; 
const messager = initMessager({
    pageName: 'xxx'
});
interface IOptions {
    pageName?: string;
    pageId?: string;
    data?: IJson;
    useSessionStorage?: boolean;
}

3.2 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;
    onPageChange(fn: IOnPageChange): () => void;
    onBeforeUnload(func: (event: BeforeUnloadEvent) => void): () => void;
    onUnload(func: (event: Event) => 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; // 关闭其他所有和当前页面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[]; // 获取所有打开的页面
        updatePageData(data: IJson, cover?: boolean): boolean; // 更新页面数据
    }
}

interface IPage {
    name: string; // 页面的名称
    id: string; // 页面id
    index: number; // 页面打开的次序
    show: boolean; // 页面是否可见
    data?: IJson; // 页面携带的数据
}
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 方法
}

3.3 postMessage 方法

function postMessage(data: any, messageType?: number | string): void;
import initMessager from 'cross-window-message'; 
const messager = initMessager();
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();
messager.onMessage((msgData)=>{
    console.log(msgData);
})

注册一个接收消息的事件

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

3.6 onPageChange

监听所有页面改变的事件,该方法会返回一个函数,执行可以用去取消此次监听

function onPageChange(fn: (newQueue: IPage[], oldQueue: IPage[]) => void): () => void;
import initMessager from 'cross-window-message'; 
const messager = initMessager();
messager.onPageChange((newQueue, oldQueue)=>{
    console.log(newQueue, oldQueue);
})

3.7 页面事件

function onBeforeUnload(func: (event: BeforeUnloadEvent) => void): () => void;
function onUnload(func: (event: Event) => void): () => void;
function onClick(func: (event: MouseEvent) => void): () => void;
function onShow(func: (event: Event) => void): () => void;
function onHide(func: (event: Event) => void): () => void;

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

参数与原生一致

3.8 工具方法

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

import initMessager from 'cross-window-message'; 
const messager = initMessager();
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[]; // 获取所有打开的页面
updatePageData(data: IJson, cover?: boolean): boolean; // 更新页面数据 cover 参数表示是否需要覆盖旧的数据,默认为false

3.9 版本

import initMessager from 'cross-window-message'; 
initMessager.version;