js 同源跨标签广播通信

话不多说直接上代码…

//BrowserChannel.js

/**
 * 作者:superzuo
 * 时间:2023/03/03 11:18:08
 * 功能:同源跨标签广播通信
 */
/* 定义mode来判断和通信 */
const MODE = {
    
    
    /* 通过工具关闭 */
    "tools-closeWin":"tools-closeWin",
    /* iportal 登录成功 */
    "user-login":"user-login",
    /* 工具申请提交 */
    "tools-applyFor":"tools-applyFor"
}

class BrowserChannel {
    
    
    constructor(name,mark) {
    
    
        this.Channel = new BroadcastChannel(name);
        this.Channel.id = this.creatId(name);
        this.mark = mark;
        this.MODE = MODE;
        /* 创建列表保存监听者 */
        this.Channel.listeners = new Set();
        /* 内容初始化 */
        this.ints()
    }

    ints() {
    
    
        /* 我是当前标签打开者,需要首次广播 */
        this.sendMsg({
    
    
            type: 1,
            text: "我来了!"
        });
        window.addEventListener("unload", () => {
    
    
            this.sendMsg({
    
    
                type: 0,
                text: "我走了!"
            });
        })
        /* 监听广播数据 */
        this.Channel.addEventListener("message", e => {
    
    
            let msg = e.data.msg;
            /* 有新标签来了 */
            if (msg.type === 1) {
    
    
                this.sendMsg({
    
    
                    type: 2,
                    text: "我收到了!"
                });
                this.Channel.listeners.add({
    
    
                    id:e.data.id,
                    mark:e.data.mark
                });
            } else if (msg.type === 2) {
    
    
                this.Channel.listeners.add({
    
    
                    id:e.data.id,
                    mark:e.data.mark
                });
            } else if (msg.type === 0) {
    
    
                this.Channel.listeners.delete({
    
    
                    id:e.data.id,
                    mark:e.data.mark
                });
            }
        })
    }

    /* 创建标签id标识监听者 */
    creatId(name) {
    
    
        const key = `Iportal-Channel-${
      
      name}`
        let id = +localStorage.getItem(key);
        if (!id) {
    
    
            id = 0;
        }
        id++;
        localStorage.setItem(key, id.toString());
        return id;
    }

    sendMsg(msg) {
    
    
        this.Channel.postMessage({
    
    
            id: this.Channel.id,
            mark:this.mark,
            msg
        })
    }

}

export default BrowserChannel;
//在main.js 加载
import BrowserChannel from "@/utils/BroadcastChannel";


/* 同源跨标签广播通信,主要用于赋能工具通信 */
let $BrowserChannel = new BrowserChannel("MyTools","MyMark");
Vue.prototype.$BrowserChannel = $BrowserChannel;
/*---------------------------------------------------------*/
/*---------------------------------------------------------*/
/* 监听窗口来关闭当前已打开窗口 */
$BrowserChannel.Channel.addEventListener("message",e=>{
    
    
    let msg = e.data.msg;
    /* 在未登录的情况下关闭当前iportal,然后重新打开 */
    if(!!msg.mode && msg.mode === $BrowserChannel.MODE["tools-closeWin"]){
    
    
        //相当于window.close()操作
        Utility.closeWinPage();
    }
})

//其他地方应用
this.$BrowserChannel.Channel.addEventListener("message", e => {
    
    
      let msg = e.data.msg;
      /* 监听用户登录 */
      if (!!msg.mode && msg.mode === this.$BrowserChannel.MODE['user-login']) {
    
    
        //登录了获取用户信息
        !!msg.success && this.getUserInfo();
      }
})

//发送广播消息
 this.$BrowserChannel.sendMsg({
    
    
     mode: this.$BrowserChannel.MODE['tools-applyFor']
 })

猜你喜欢

转载自blog.csdn.net/qq_39244619/article/details/130947554
今日推荐