维护别人遗留的老项目相当头疼,遇到一个遗留的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下的父子交互事件封装/
许可协议: 转载请保留原文链接及作者。