Skip to content

Commit

Permalink
fix: 子应用window事件监听增加message事件,增加事件监听target可选参数 (#555)
Browse files Browse the repository at this point in the history
close #549
  • Loading branch information
UmbraCi authored May 27, 2023
1 parent cdc4e3d commit 2255301
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 22 deletions.
16 changes: 16 additions & 0 deletions examples/main-vue/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,27 @@ export default {
degrade: window.Proxy,
};
},
mounted() {
window.addEventListener("message", this.handleMessage);
},
beforeDestroy() {
window.removeEventListener("message", this.handleMessage);
},
methods: {
close() {
if (this.active) this.active = false;
},
handleFlag(name) {
this[name + "Flag"] = !this[name + "Flag"];
},
handleMessage(event) {
if (event.origin === location.origin && event.source !== window) {
console.log("父应用接收到消息:", event.data);
alert("父应用接收到消息:" + event.data);
// 将消息发送给子应用
event.source.postMessage("Hello 子应用,我是父应用!", event.origin);
}
},
},
};
</script>
Expand All @@ -105,6 +119,7 @@ body {
height: 100vh;
--theme: rgb(241, 107, 95);
}
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
Expand Down Expand Up @@ -165,6 +180,7 @@ body {
transform: translate(0, 0);
box-shadow: 3px 0px 9px 2px #e6e6e6;
}
#nav .menu-icon {
position: absolute;
left: 100%;
Expand Down
25 changes: 25 additions & 0 deletions examples/react17/src/Communication.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,25 @@ export default class Communication extends React.Component {
handleEmit = () => {
window.$wujie && window.$wujie.bus.$emit("click", "react17");
};

printfMessage = (e) => {
console.log('父级发过来的消息:',e.data)
alert('父级发过来的消息:' + e.data)
}

sendPostMessage = () => {
// 向父级窗口发送消息
window.parent.postMessage('Hello 父应用,我是子应用!', '*');
};

componentDidMount() {
window.addEventListener("message", (e)=>this.printfMessage(e), { targetWindow: window.__WUJIE_RAW_WINDOW__ });
}

componentWillUnmount() {
window.removeEventListener("message", (e)=>this.printfMessage(e), { targetWindow: window.__WUJIE_RAW_WINDOW__ });
}

render() {
return (
<div>
Expand All @@ -38,6 +57,12 @@ export default class Communication extends React.Component {
<p>
<Button onClick={this.handleEmit}>显示alert</Button>
</p>
<h3>4、通过window.parent.postMessage()方法往父级发送消息</h3>
<p>父子应用通过postmessage传递消息</p>
<p>message监听和发送的时候注意source</p>
<p>
<Button onClick={this.sendPostMessage}>postMessage发送消息</Button>
</p>
</div>
</div>
);
Expand Down
3 changes: 3 additions & 0 deletions packages/wujie-core/src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ export interface SandboxCache {
options?: cacheOptions;
}

export type appAddEventListenerOptions = AddEventListenerOptions & { targetWindow?: Window };

// 全部无界实例和配置存储map
export const idToSandboxCacheMap = window.__POWERED_BY_WUJIE__
? window.__WUJIE.inject.idToSandboxMap
Expand Down Expand Up @@ -163,6 +165,7 @@ export const appWindowAddEventListenerEvents = [
"load",
"beforeunload",
"unload",
"message",
];

// 子应用window.onXXX需要挂载到iframe沙箱上的事件
Expand Down
15 changes: 9 additions & 6 deletions packages/wujie-core/src/iframe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
rawWindowAddEventListener,
rawWindowRemoveEventListener,
} from "./common";
import type { appAddEventListenerOptions } from "./common";
import { getJsLoader } from "./plugin";
import { WUJIE_TIPS_SCRIPT_ERROR_REQUESTED, WUJIE_DATA_FLAG } from "./constant";
import { ScriptObjectLoader } from "./index";
Expand Down Expand Up @@ -113,13 +114,14 @@ function patchIframeEvents(iframeWindow: Window) {
iframeWindow.addEventListener = function addEventListener<K extends keyof WindowEventMap>(
type: K,
listener: (this: Window, ev: WindowEventMap[K]) => any,
options?: boolean | AddEventListenerOptions
options?: boolean | appAddEventListenerOptions
) {
// 运行插件钩子函数
execHooks(iframeWindow.__WUJIE.plugins, "windowAddEventListenerHook", iframeWindow, type, listener, options);

if (appWindowAddEventListenerEvents.includes(type)) {
return rawWindowAddEventListener.call(iframeWindow, type, listener, options);
if (appWindowAddEventListenerEvents.includes(type) || (typeof options === "object" && options.targetWindow)) {
const targetWindow = typeof options === "object" && options.targetWindow ? options?.targetWindow : iframeWindow;
return rawWindowAddEventListener.call(targetWindow, type, listener, options);
}
// 在子应用嵌套场景使用window.window获取真实window
rawWindowAddEventListener.call(window.__WUJIE_RAW_WINDOW__ || window, type, listener, options);
Expand All @@ -128,13 +130,14 @@ function patchIframeEvents(iframeWindow: Window) {
iframeWindow.removeEventListener = function removeEventListener<K extends keyof WindowEventMap>(
type: K,
listener: (this: Window, ev: WindowEventMap[K]) => any,
options?: boolean | AddEventListenerOptions
options?: boolean | appAddEventListenerOptions
) {
// 运行插件钩子函数
execHooks(iframeWindow.__WUJIE.plugins, "windowRemoveEventListenerHook", iframeWindow, type, listener, options);

if (appWindowAddEventListenerEvents.includes(type)) {
return rawWindowRemoveEventListener.call(iframeWindow, type, listener, options);
if (appWindowAddEventListenerEvents.includes(type) || (typeof options === "object" && options.targetWindow)) {
const targetWindow = typeof options === "object" && options.targetWindow ? options?.targetWindow : iframeWindow;
return rawWindowRemoveEventListener.call(targetWindow, type, listener, options);
}
rawWindowRemoveEventListener.call(window.__WUJIE_RAW_WINDOW__ || window, type, listener, options);
};
Expand Down
44 changes: 28 additions & 16 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 2255301

Please sign in to comment.