美文网首页
ifram下的父子交互事件封装

ifram下的父子交互事件封装

作者: DLLCNX | 来源:发表于2021-03-29 11:02 被阅读0次

    维护别人遗留的老项目相当头疼,遇到一个遗留的ifram模式做的一个项目,每次的交互都采用一个一个来,自己维护的相当崩溃,重构客户也不愿意。好吧,时间紧急,简单封装一个事件机制来稍微减轻自己的麻烦吧。利用了localStorage的监听机制结合简单的事件总线机制来实现。

    创建引入全局js

    1.父页面引入parent.js

    /**
     * @author  DLLCN
     * @time    2020/8/28 4:57 下午
     * @title   应用间事件交互
     * @desc
     *
     */
     window.gos = {event: {}};
     gos.event.eventMap = new Map()
     gos.event.emit = function (eventType, data) {
         const time = new Date().getTime();
         const event = {key: eventType, data: data, timestamp: time}
         const detail = JSON.stringify(event);
         localStorage.setItem(`gos.event.${eventType}`, detail)
     }
     gos.event.addEventListener = function (eventType, func) {
         let evtSet = gos.event.eventMap.get(eventType)
         if (!evtSet) {
             evtSet = new Set()
             gos.event.eventMap.set(eventType, evtSet)
         }
         evtSet.add(func)
     }
     gos.event.removeEventListener = function (eventType, func) {
         let evtSet = gos.event.eventMap.get(eventType)
         if (evtSet) {
             evtSet.delete(func)
         }
     }
     
     let oriSetItem = localStorage.setItem;
     localStorage.setItem = function (key, value) {
         //这里抛出自定义事件
         var event = new Event("setItemEvent");
         event.newValue = value;
         event.key = key;
         window.dispatchEvent(event);
     
         //实现原方法
         oriSetItem.apply(this, arguments);
     }
     window.addEventListener('setItemEvent', e => {
         var str = e.key;
         if (/^gos\.event\..{1,}$/.test(str)) {
             const data = JSON.parse(e.newValue);
             let evtSet = gos.event.eventMap.get(data.key)
             if (evtSet) {
                 for (let item of evtSet.values()) {
                     item(data);
                 }
             }
         }
     }, false)
    

    2.子页面引入children.js

    window.gos = top.gos || {};
    if(!top || !top.gos || JSON.stringify(top.gos) === '{}'){
        console.error('主界面未引入js,只能使用本地事件服务,无法父子交互!')
    }
    
    if (!gos.event) {
        // console.log('渲染本地事件服务!')
        gos.event = {};
        /**
        * 事件
        * @param {*} eventType
        * @param {*} data
        */
        gos.event.eventMap = new Map()
        gos.event.emit = function (eventType, data) {
            const time = new Date().getTime();
            const event = { key: eventType, data: data, timestamp: time }
            const detail = JSON.stringify(event);
            localStorage.setItem(`gos.event.${eventType}`, detail)
        }
        gos.event.addEventListener = function (eventType, func) {
            let evtSet = gos.event.eventMap.get(eventType)
            if (!evtSet) {
                evtSet = new Set()
                gos.event.eventMap.set(eventType, evtSet)
            }
            evtSet.add(func)
        }
        gos.event.removeEventListener = function (eventType, func) {
            let evtSet = gos.event.eventMap.get(eventType)
            if (evtSet) {
                evtSet.delete(func)
            }
        }
    }
    
    
    const oriSetItem = localStorage.setItem;
    localStorage.setItem = function (key, value) {
        //这里抛出自定义事件
        var event = new Event("setItemEvent");
        event.newValue = value;
        event.key = key;
        window.dispatchEvent(event);
    
        //实现原方法
        oriSetItem.apply(this, arguments);
    }
    window.addEventListener('setItemEvent', e => {
        var str = e.key;
        if (/^gos\.event\..{1,}$/.test(str)) {
            const data = JSON.parse(e.newValue);
            let evtSet = gos.event.eventMap.get(data.key)
            if (evtSet) {
                for (let item of evtSet.values()) {
                    item(data);
                }
            }
        }
    }, false)
    

    使用方法

        // 发送事件
        gos.event.emit('test', { key: 'parent' })
    
        // 接收事件
        gos.event.addEventListener('test', () => {
                console.log('接收到事件。');
        })
    

    源码

    原始链接:http://dllcny.com:10020/2021/03/18/ifram下的父子交互事件封装/

    许可协议: 转载请保留原文链接及作者。

    相关文章

      网友评论

          本文标题:ifram下的父子交互事件封装

          本文链接:https://www.haomeiwen.com/subject/lqzvhltx.html