mirror of
https://github.com/NetEase/tango.git
synced 2026-08-28 17:41:30 +08:00
fix: use addEventListener to bind iframe event handlers (#169)
* feat: use addEventListener to bind iframe event handlers * fix: types
This commit is contained in:
@@ -3,7 +3,13 @@ import { TangoEventName } from '@music163/tango-helpers';
|
||||
import Loading from './loading';
|
||||
import Manager from './manager';
|
||||
import { createMissingPackageJSON, changeRoute } from './helper';
|
||||
import { IFiles, CodeSandboxState, CodeSandboxProps, UnsubscribeFunction } from '../types';
|
||||
import {
|
||||
IFiles,
|
||||
CodeSandboxState,
|
||||
CodeSandboxProps,
|
||||
UnsubscribeFunction,
|
||||
EventHandlers,
|
||||
} from '../types';
|
||||
|
||||
// CodeSandbox 使用示例
|
||||
// <CodeSandbox files={files} entry={entry} template={template} bundlerURL={`${window.location.protocol}//codesandbox.fn.netease.com/`} />
|
||||
@@ -32,6 +38,8 @@ export class CodeSandbox extends React.Component<CodeSandboxProps, CodeSandboxSt
|
||||
|
||||
iframe: HTMLIFrameElement;
|
||||
|
||||
private eventHandlers: EventHandlers;
|
||||
|
||||
constructor(props: CodeSandboxProps) {
|
||||
super(props);
|
||||
|
||||
@@ -75,11 +83,8 @@ export class CodeSandbox extends React.Component<CodeSandboxProps, CodeSandboxSt
|
||||
this.manager.cleanup();
|
||||
|
||||
// clear tango event
|
||||
if (this.iframe && this.props?.eventHandlers?.onTango) {
|
||||
this.iframe.contentDocument?.removeEventListener(
|
||||
TangoEventName.DesignerAction,
|
||||
this.props.eventHandlers.onTango,
|
||||
);
|
||||
if (this.iframe && this.eventHandlers) {
|
||||
this.unbindEvents(this.eventHandlers);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,6 +121,29 @@ export class CodeSandbox extends React.Component<CodeSandboxProps, CodeSandboxSt
|
||||
externalResources: this.props.externalResources,
|
||||
});
|
||||
|
||||
normalizeEventType = (eventType: string) =>
|
||||
eventType === 'onTango'
|
||||
? TangoEventName.DesignerAction
|
||||
: eventType.replace(/^on/, '').toLowerCase();
|
||||
|
||||
bindEvents = (eventHandlers: EventHandlers) => {
|
||||
Object.keys(eventHandlers).forEach((eventType) => {
|
||||
this.iframe?.contentDocument?.addEventListener(
|
||||
this.normalizeEventType(eventType),
|
||||
eventHandlers[eventType],
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
unbindEvents = (eventHandlers: EventHandlers) => {
|
||||
Object.keys(eventHandlers).forEach((eventType) => {
|
||||
this.iframe?.contentDocument?.removeEventListener(
|
||||
this.normalizeEventType(eventType),
|
||||
eventHandlers[eventType],
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
// Manager 实例化,即开始构建页面
|
||||
// 将 el 传给 Manager 作为实例化参数,当构建完成后,会将构建的页面 dom 设置给 el
|
||||
// 注:Manager是一个管理者的角色,从大局上把控整个转译和执行的流程
|
||||
@@ -155,17 +183,11 @@ export class CodeSandbox extends React.Component<CodeSandboxProps, CodeSandboxSt
|
||||
|
||||
// 注册监听函数
|
||||
const { eventHandlers } = this.props;
|
||||
Object.keys(eventHandlers).forEach((eventType) => {
|
||||
if (el.contentDocument) {
|
||||
el.contentDocument[eventType.toLowerCase()] = eventHandlers[eventType];
|
||||
}
|
||||
if (eventType === 'onTango') {
|
||||
el.contentDocument?.addEventListener(
|
||||
TangoEventName.DesignerAction,
|
||||
eventHandlers[eventType],
|
||||
);
|
||||
}
|
||||
});
|
||||
if (eventHandlers) {
|
||||
this.bindEvents(eventHandlers);
|
||||
// 保存一份当前的 eventHandlers,避免 props 变更导致无法取消现在已注册的事件绑定
|
||||
this.eventHandlers = eventHandlers;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user