Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 子应用window事件监听增加message事件,增加事件监听target可选参数 #555

Merged
merged 1 commit into from
May 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.