@ciolabs/framecast (英语)
TypeScript 跨帧通信库
安装
npm install @ciolabs/framecast
广播
广播允许您发送单向通信。 这个 broadcast 当收到有效广播时,事件会释放.
您可以添加许多听众到 broadcast 活动.
唯一的论点包含一个带有去序列化消息的对象. 所有通过帧cast发送的数据必须是有效的JSON.
示例
家长
import { Framecast } from '@ciolabs/framecast';
const target = document.querySelector('iframe').contentWindow;
const framecast = new Framecast(target);
framecast.on('broadcast', (message: any) => {
console.log(message);
});
儿童
import { Framecast } from '@ciolabs/framecast';
const target = window.parent;
const framecast = new Framecast(target);
framecast.broadcast('Hello world');
职能
Framcast允许您调用跨帧函数 。 这个 function:* 调用时会发出事件。 收听器的返回值被传递回调用框.
说明,与 broadcast 事件, function:* 事件只能有一个听众。 所有通过帧cast发送的数据必须是有效的JSON.
创建函数
通过为您添加一个收听器创建函数 function:* 发生 * 是函数的名称。 因此在下面的示例中,函数名称是 getElementId 所以,我们命名事件 function:getElementId。 。 。 .
儿童
import { Framecast } from '@ciolabs/framecast';
const target = window.parent;
const framecast = new Framecast(target);
framecast.on('function:getElementId', selector => {
return document.querySelector(selector).getAttribute('id');
});
调用函数
要从另一个框架调用函数, 我们使用 call。注意,所有函数返回一个承诺,即使另一端的处理器是一个同步函数.
家长
import { Framecast } from '@ciolabs/framecast';
const target = document.querySelector('iframe').contentWindow;
const framecast = new Framecast(target);
const bodyId = await framecast.call('getElementId', 'body');
处理错误
您处理错误的方式与函数在同一框架中一样。 在尝试/抓取中包入函数调用 .
try {
const bodyId = await framecast.call('getElementId', 'body');
} catch (error) {
console.log('Something went wrong', error);
}
默认情况下, 如果处理器需要超过10秒才能完成, Framcast 将会丢出一个错误 。 您可以自定义此选项 config.functionTimeoutMs 选项.
有些时候,你不希望某个函数为个别电话超时. 你用得着 waitFor 调用一个没有超时的函数。 它会回来 result 财务报告和审定财务报表 dispose 函数。 这个 dispose 函数将删除听众.
const { result, dispose } = framecast.waitFor('getElementId', 'body');
console.log(await result);
共享状态
Framcast支持父母与孩子框架之间的共享状态. 这是通过使用 nanostores。 。 。 .
每个州都是 atom 并可以订阅。 当状态在一个框架中更新时,它将在另一个框架中更新.
创建共享状态
您可以通过调用创建共享状态 state {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}在编剧中 第一种说法是州名,第二种说法是起先值.
const $counter = framecast.state('counter', 0);
$counter.subscribe(value => {
console.log('counter', value);
});
初始创建时, 状态将被设定为初始值 。 如果状态已经存在于另一个框架,则会被同步到另一个框架的值.
注意: 您必须订阅状态才能挂载 .
示例
在以下例子中,父母或子女框架更新 $counter 将更新其他框架.
在父母和孩子的构架中相容.
儿童
import { Framecast } from '@ciolabs/framecast';
const framecast = new Framecast(window.parent);
const $counter = framecast.state('counter', 0);
$counter.subscribe(value => {
console.log('counter', value);
});
document.querySelector('button').addEventListener('click', () => {
$counter.set($counter.get() + 1);
});
家长
import { Framecast } from '@ciolabs/framecast';
import { persistentAtom, setPersistentEngine } from '@nanostores/persistent';
const framecast = new Framecast(document.querySelector('iframe').contentWindow);
$counter.subscribe(value => {
console.log('counter', value);
});
评价任意代码
Framcast 的内置函数命名为 evaluate。此选项在目标窗口中评估给定的函数.
儿童的帧实例必须选择使用该特性,设置 config.supportEvaluate 改为 true这样做会带来安全风险 eval() 所以,仔细考虑 在启用这一点之前.
这是受剧作家的启发 评价 函数.
儿童
import { Framecast } from '@ciolabs/framecast';
const target = window.parent;
const framecast = new Framecast(target, { supportEvaluate: true });
家长
import { Framecast } from '@ciolabs/framecast';
const target = document.querySelector('iframe').contentWindow;
const framecast = new Framecast(target);
const bodyId = await framecast.evaluate(() => document.querySelector('body').getAttribute('id'));
传递论据
通过将参数作为附加参数传递到 evaluate。参数可以是 可序列 数值.
import { Framecast } from '@ciolabs/framecast';
const target = document.querySelector('iframe').contentWindow;
const framecast = new Framecast(target);
const bodyId = await framecast.evaluate(selector => document.querySelector(selector).getAttribute('id'), 'body');
API 密码
constructor(target: Window, config: FramecastConfig);
// broadcasts
on(type: 'broadcast', listener: (message: any) => void);
off(type: 'broadcast', listener: (message: any) => void);
broadcast(message: any);
// functions
on(type: `function:${string}`, listener: (...args: any[]) => void);
off(type: `function:${string}`, listener: (...args: any[]) => void);
call(type: `function:${string}`, ...args: any[]) => Promise<any>;
waitFor(type: `function:${string}`, ...args: any[]) => { result: Promise<any>, dispose: () => void };
// evaluate
evaluate<ReturnType = any>(fn: (...args: any[]) => ReturnType, ...args: any[]) => Promise<ReturnType>;
type FramecastConfig = {
origin: string | null;
channel: string | null;
self: Window | null;
functionTimeoutMs: number;
supportEvaluate: boolean;
};
灵感来自 标签