Skip to main content
New Participant
January 6, 2020
Answered

keyboard events in iframe

  • January 6, 2020
  • 2 replies
  • 11714 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 has been closed for replies.
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.

 

2 replies

New 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.
Brainiac
January 6, 2020

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

New 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
Brainiac
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.