最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to senddispatch keypress events to an embedded iframe in React? - Stack Overflow

programmeradmin1浏览0评论

I have an iframe of Google Slides which I embedded in my web app.
The iframe implementation is:

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

I want to listen to click events on the main web page (while the iframe is not necessarily in focus), then create their corresponding keypress events - and pass them to the iframe, thus making the slideshow iframe to trigger and react to the user key presses.

I tried something like this:

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

But it doesn't work - it only focuses on the iframe, but doesn't send the arrow key event.
I saw some solutions using the parent document inside the iframe or sending messages with postMessage, but I can't add any code inside my iframe since its origin is an external link.

I have an iframe of Google Slides which I embedded in my web app.
The iframe implementation is:

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

I want to listen to click events on the main web page (while the iframe is not necessarily in focus), then create their corresponding keypress events - and pass them to the iframe, thus making the slideshow iframe to trigger and react to the user key presses.

I tried something like this:

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

But it doesn't work - it only focuses on the iframe, but doesn't send the arrow key event.
I saw some solutions using the parent document inside the iframe or sending messages with postMessage, but I can't add any code inside my iframe since its origin is an external link.

Share Improve this question edited Dec 30, 2020 at 15:21 amiregelz asked Dec 30, 2020 at 14:47 amiregelzamiregelz 1,8757 gold badges30 silver badges51 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 7

Due to restrictions imposed by the Same Origin Policy implemented by all modern browsers, I don't think you'll be able to do what you intend to do - this is not related to React, the browser will just not allow for a script on the parent window to trigger any kind DOM event on the child iframe programmatically.

That's why you saw references to the postMessage API when you searched for a solution. That API was introduced to enable cross-origin munication between window objects in a safer, more controlled manner.

The code you've posted would execute any event listener that might appended to the parent window's DOM iframe element, so something like this:

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

Should be triggered by your code. But this is happening on the parent window, the javascript "running" within iframe (i.e. Google's code responsible for changing the current slide) doesn't have access nor is able to "see" that event.

If both the iframe and your webpage were serviced from the same domain (in other words, if they had the same "origin"), what I think you're trying to achieve would be something more in the lines of:

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()
}

But again this'd only work if both the iframe and parent window were considered to have the "same origin" by the browser (which isn't your case).

Albeit significantly more plicated, you could probably achieve something close to what you're looking for (at the cost of rebuilding the design of some webpages, at least) by querying Google Slides using the corresponding Google API.

Check out the corresponding documentation: https://developers.google./slides/quickstart/javascript

It may look scary at first, but once you've got used to it, Google APIs don't bite that much, you can even create a service account and grant it access to your document so that your app can read the document and update it without asking the user to authorize your app.

发布评论

评论列表(0)

  1. 暂无评论