如何 send/dispatch 按键事件到 React 中的嵌入式 iframe?

How to send/dispatch keypress events to an embedded iframe in React?

我有一个包含 Google 个幻灯片的 iframe,我将其嵌入到我的网络应用程序中。
iframe 实现是:

<iframe ref={slidesRef} src={src} width='100%' height='100%' allowFullScreen={true}/>

我想监听主网页的点击事件(而iframe不一定是focus),然后创建它们对应的按键事件-并将它们传递给iframe,从而使幻灯片iframe触发和对用户按键做出反应。

我试过这样的事情:

    function onButtonClick(e) {
        e.stopPropagation();
        slidesRef.current.focus();
        slidesRef.current.dispatchEvent(new KeyboardEvent('keypress', {
            key: 'ArrowRight', which : 39
        }));
    }

但它不起作用 - 它只关注 iframe,但不发送箭头键事件。
我看到一些解决方案使用 iframe 内的父文档或使用 postMessage 发送消息,但我无法在 iframe 内添加任何代码,因为它的来源是外部 link.

由于所有现代浏览器实施的 Same Origin Policy 所施加的限制,我认为您无法执行您想要执行的操作 - 这与 React 无关,浏览器会只是不允许父 window 上的脚本以编程方式触发子 iframe 上的任何类型 DOM 事件。

这就是为什么您在搜索解决方案时看到对 postMessage API 的引用。引入 API 是为了以更安全、更可控的方式实现 window 对象之间的跨域通信。

您发布的代码将执行可能附加到父 window 的 DOM iframe 元素的任何事件侦听器,因此如下所示:

<iframe onkeydown="console.log('keydow')" src="https://google/..." />

应该由您的代码触发。但这发生在父 window 上,iframe 中的 javascript“运行”(即 Google 负责更改当前幻灯片的代码)不会无法访问也无法“看到”该事件。

如果 iframe 和您的网页都来自同一域(换句话说,如果它们具有相同的“来源” "),我认为您要实现的目标更多的是:

function onButtonClick(e) {
  e.stopPropagation()

  // Note that we're retrieving a DOM element from the iframe's window object,
  // not the parent's one
  const iframeBody = slidesRef.current.contentDocument.body;

  // Get an element on the iframe's document which has an event listener attached
  // to it that changes the current slide
  const sliderEl = iframeBody.querySelector('...')
  sliderEl.click()
}

但是,这只有在 iframeparent window 被浏览器认为具有“同源”时才有效(这不是你的情况).

尽管要复杂得多,但您可能会通过使用相应的 Google API.

查看相应的文档:https://developers.google.com/slides/quickstart/javascript

一开始可能看起来很可怕,但是一旦你习惯了,Google API就不会那么咬人了,你甚至可以创建一个服务帐户并授予它访问您的文档,以便您的应用程序可以读取文档并更新文档,而无需请求用户授权您的应用程序。