Skip to main content
Participant
January 6, 2020
Answered

keyboard events in iframe

  • January 6, 2020
  • 6 replies
  • 11870 views

Hi,

in a game i use keyboard events in canvas/html. in normal exported html all works fine.

Trying to play the game in an separate html with  iframe-tag,  keyboard events are nor recognized.

Is there a workaround for this?

Kind regards.

This topic is closed to new replies. Start a new post to keep the conversation going.
Correct answer ClayUUID

You'll have to forward keyboard events from the parent frame to the iframe. If your content will always be on a web server, and the parent frame and iframe content will always be on the same domain, you can use cross-document scripting. You'd put something like this in the parent document:

 

window.myIframe = document.getElementById("whatever the ID of your iframe is").contentWindow;
window.addEventListener("keydown", function(evt) { myIframe.myKeydownEventHandler(evt); });

 

However, if you try to run this from a local drive, or the parent page and iframe content will ever be on different servers, the above will trigger an XSS (cross-site scripting) error in the browser. The solution in this case is to use postMessage(), which is slightly more complicated. In the parent document you'd have:

 

window.myIframe = document.getElementById("whatever the ID of your iframe is").contentWindow;
window.addEventListener("keydown", function(evt) { myIframe.postMessage(JSON.stringify({type:"KeyboardEvent", key:evt.key})); });

 

Then in the iframe document you'll need another function:

 

window.addEventListener("message", handleMessage);
function handleMessage(evt) {
	var msg = JSON.parse(evt.data);
	if (typeof msg === "object" && msg.type && msg.type === "KeyboardEvent") {
		window.dispatchEvent("keydown", {key:msg.key});
	}
}

 

I must stress the above has not been tested. But the general idea is to grab the "key" value from the keyboard event, then post it as a message to the iframe, which catches the message and uses its data to attempt to spoof a local keyboard event, which should be picked up by your already-extant keyboard event listener. This last part might not work as-is because it's not sending a proper Event object with all the usual properties. You could work around the event-spoofing entirely by just adding a third function, called by both your message and keyboard listeners, that directly accepts and acts upon the key value.

 

6 replies

Participant
January 6, 2020
hi, thanks for the immediate answer.
in the meantime i googled for iframe and keyboard eventerrors  and found
this snippet, which works for me.
if the html is in the same directory, it works also for me without server.

<br>scrolling="no" width="550" height="400">


if i have to set the iframe-source to different servers, i will have to
study your post again.
thanks for all.
Legend
January 6, 2020

I guess we just have to imagine what the snippet was.

Participant
January 6, 2020

...oops, my code was wrong formatted, sorry.

<iframe id="EdgeID" src="myanimate.html" style="overflow:hidden" scrolling="no" width="550" height="400"></iframe>
<script>
    setTimeout(machet,100);
    function machet() {
        //alert("machet");
        document.getElementById("EdgeID").contentWindow.focus();
    }
</script>

 

ClayUUIDCorrect answer
Legend
January 6, 2020

You'll have to forward keyboard events from the parent frame to the iframe. If your content will always be on a web server, and the parent frame and iframe content will always be on the same domain, you can use cross-document scripting. You'd put something like this in the parent document:

 

window.myIframe = document.getElementById("whatever the ID of your iframe is").contentWindow;
window.addEventListener("keydown", function(evt) { myIframe.myKeydownEventHandler(evt); });

 

However, if you try to run this from a local drive, or the parent page and iframe content will ever be on different servers, the above will trigger an XSS (cross-site scripting) error in the browser. The solution in this case is to use postMessage(), which is slightly more complicated. In the parent document you'd have:

 

window.myIframe = document.getElementById("whatever the ID of your iframe is").contentWindow;
window.addEventListener("keydown", function(evt) { myIframe.postMessage(JSON.stringify({type:"KeyboardEvent", key:evt.key})); });

 

Then in the iframe document you'll need another function:

 

window.addEventListener("message", handleMessage);
function handleMessage(evt) {
	var msg = JSON.parse(evt.data);
	if (typeof msg === "object" && msg.type && msg.type === "KeyboardEvent") {
		window.dispatchEvent("keydown", {key:msg.key});
	}
}

 

I must stress the above has not been tested. But the general idea is to grab the "key" value from the keyboard event, then post it as a message to the iframe, which catches the message and uses its data to attempt to spoof a local keyboard event, which should be picked up by your already-extant keyboard event listener. This last part might not work as-is because it's not sending a proper Event object with all the usual properties. You could work around the event-spoofing entirely by just adding a third function, called by both your message and keyboard listeners, that directly accepts and acts upon the key value.