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

只谈情不闲聊 提交于 2021-01-28 08:54:47

问题


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.


回答1:


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 communication 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).




回答2:


Albeit significantly more complicated, 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.com/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.



来源:https://stackoverflow.com/questions/65508816/how-to-send-dispatch-keypress-events-to-an-embedded-iframe-in-react

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!