I've been trying to set up this test page for my flash game but it refuses to gain focus on load. I read a bunch of forum entries and didn't get it to do anything, I can't really believe this should be so hard.
Here's what I have:
<head>
<title>UP HERE WE ESCAPE THE RAT RACE</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>
<script type="text/javascript">
swfobject.embedSWF("UpHere.swf", "myContent", "700", "300", "9.0.0");
function setFocusOnFlash() {
var fl = document.getElementById("myContent");
if (fl) { fl.focus(); }
}
</script>
</head>
<body onload="setFocusOnFlash()">
<div style="margin:0 auto; text-align:center; width:700px;">
<div id="myContent" style="margin:0 auto; text-align:center; width:700px;">
<p>Alternative content</p>
</div>
</div>
</body>
You can see it live here, http://joon.be/exclusivepreview/
what's wrong with it? I don't have a very deep knowledge of swfObject...
I have found a way that works for me on Firefox 16, Chrome 23 and IE 8 (these are where I have tested it so far). Of course, this is a bunch of hacks so who knows if it will work forever... but it certainly doesn't make things worse.
function setFocusOnFlash() {
var flash = document.getElementById("theIdOfTheObjectElement");
flash.tabIndex = 1234; // This was needed on Chrome 23
flash.focus();
// Attention: FireFox needs wmode "opaque"!
}
On Firefox only, <param name="wmode" value="opaque">
under the object
element was also needed, or else focus()
had no effect. (I have used Stephen Belanger's jquery.flash
, where you can specify wmode
; I assume it's also possible with SWFObject
.)
But the trickier part is that you must not call setFocusOnFlash
too early. For Chrome and IE, adding setTimeout(setFocusOnFlash, 1)
directly after the JavaScript that inserts the object has worked. Directly issuing setFocusOnFlash()
didn't. I assume the trick is simply that the timed callbacks are only called after the browser has fully processed the document change, regardless of the delay you specify. But on Firefox calling with this small delay was too early; it has put a dotted border around the object
element (it shouldn't) and Flash didn't get the key strokes. Setting the delay to 250 has fixed this on my computer, but who knows how big delay you need. (Worse, repeating the setFocusOnFlash
calls didn't help either... once that dotted border was there, they had no further effect.) So, what I did instead is adding an ExternalInterface.call("flashLoaded")
callback to the flash document class constructor. To be clear, you do that in Flash/ActionScript, so you need access to the source or to the author of the SWF file. This way, when the SWF starts, it calls the flashLoaded
JavaScript method of the embedding HTML page, so you know it's ready. The function was like:
function flashLoaded() {
// Oddly, directly calling setFocusOnFlash() didn't work on IE8
setTimeout(setFocusOnFlash, 1);
}
The way to do this is to use ExternalInterface and send the focus to Flash using a JS listener on the tab event (i.e. as the tab moves away from the element before Flash). In practice it's hard and the stage.focus handling in your AS needs to deal with some, erm, quirks. But it does work pretty much cross browser
I was desperately looking to get this work, just to speed up my own Flash game development to avoid having to click every single time to test my game. So I didn't care if it works in all browsers, so here's one that works only on Chrome.
<body onload='document.getElementById("haxe").focus();'>
<embed src="game.swf" id="haxe" ...
If you've tried focus() before and it didn't work for you, note that you have to use just the embed tag, not the object and param version.
Tested on Chrome Version 40.0.2214.93 (64-bit).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With