Skip to content

Commit

Permalink
fix: use addEventListener to bind iframe event handlers (#169)
Browse files Browse the repository at this point in the history
* feat: use addEventListener to bind iframe event handlers

* fix: types
  • Loading branch information
ccloli authored May 31, 2024
1 parent 28040fc commit c1306e2
Showing 1 changed file with 39 additions and 17 deletions.
56 changes: 39 additions & 17 deletions packages/sandbox/src/code-sandbox/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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/`} />
Expand Down Expand Up @@ -32,6 +38,8 @@ export class CodeSandbox extends React.Component<CodeSandboxProps, CodeSandboxSt

iframe: HTMLIFrameElement;

private eventHandlers: EventHandlers;

constructor(props: CodeSandboxProps) {
super(props);

Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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是一个管理者的角色,从大局上把控整个转译和执行的流程
Expand Down Expand Up @@ -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;
}
};
}
};
Expand Down

0 comments on commit c1306e2

Please sign in to comment.