Is there an existing javascript library for relaying key press events in the browser (or certain divs) into flash? I am hoping there might be a library kind of like this one for mousewheel events ?
Something like this handles javascript keyboard shortcuts great. I suppose I could just listen for those events and pass the ones I want into flash?
EDIT: These are great examples, however, if flash has focus, then javascript keystrokes are lost. How can you ensure that all key events go through javascript?
Here's another example using jQuery. You can see some sort of demo here. It traces the keypresses from the browser to a textbox.
Your JavaScript would be
var altPressed = false;
var ctrlPressed = false;
function getFlashMovie(movieName)
{
var isIE = navigator.appName.indexOf("Microsoft") != -1;
return (isIE) ? window[movieName] : document[movieName];
}
function sendCode(code) {
movie = getFlashMovie('keyboard-listener');
movie.keyEvent(code);
}
function activeKey(e) {
e.preventDefault();
if (e.which == 18) altPressed = true;
if (e.which == 17) ctrlPressed = true;
if ((e.which != 18)&&(e.which != 17)) sendCode((altPressed?'alt+':'')+(ctrlPressed?'ctrl+':'')+String.fromCharCode(e.which));
}
function inactiveKey(e) {
if (e.which == 18) altPressed = false;
if (e.which == 17) ctrlPressed = false;
}
$(document).ready(function() {
$(document).keydown(activeKey);
$(document).keyup(inactiveKey);
});
Inside the Flash movie, you would have the following code:
ExternalInterface.addCallback('keyEvent',keyEvent);
function keyEvent(code:String):void {
// do something with the "code" parameter, that looks like "alt+ctrl+D", may use .split('+'), etc
}
You'll need to import jQuery in your html file and that's about it. jQuery is cross-browser, so no problems should arise. Tested on Safari, Firefox and Opera (OSX).
Here's an example using SWFObject / javascript / AS3 + ExternalInterface
It may use some adaption to work cross-browser. I tried it on FF3(OSX) only.
First a document class containing a simple log field (for traces).
It simply defines an ExternalInterface callback listening to a method call named flashLog that will handled by the private method setMessage(...params)
package
{
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.external.ExternalInterface;
import flash.text.TextField;
public class KeyStroke extends Sprite
{
private var tf:TextField;
public function KeyStroke()
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
tf = addChild(new TextField()) as TextField;
tf.autoSize = 'left';
if(ExternalInterface.available)
{
if(ExternalInterface.addCallback("flashLog", setMessage))
{
tf.text = "addCallback() failed :(";
}
else
{
tf.text = "flash waiting";
}
}
else
{
setMessage("ExternalInterface not available!");
}
}
private function setMessage(...params):void
{
tf.text = "message : " + params.toString();
}
}
}
Embed the exported SWF via SWFObject adding the allowScriptAccess attribute, you will also need to give an id so we can locate the SWF further on (in this case 'myMovie') :
var so = new SWFObject('KeyStroke.swf', 'myMovie', '800', '100', '9', '#f0f0f0');
so.addParam("allowScriptAccess","always");
so.write('content');
Create a javascript function to handle the key presses :
<script type="text/javascript">
function keyPressHandler(e)
{
// Calls the registered callback within the flash movie
getMovie('myMovie').flashLog("Key Down!"+e.charCode)
}
function getMovie(movieName) {
return document.getElementById(movieName);
}
</script>
Register the keyPressHandler somehow (there's better ways with prototype etc.) :
<body onKeyPress="keyPressHandler(event);" >
That should be it.
Replaced ctrl with alt/option key, but it doesn't handle option down on mac:
this works:
//WORKS ONLY IN BROWSER:
//tested on SAFARI 4.0 Mac and Firefox 3.5 Mac
function onKey_Up(e:KeyboardEvent):void {
tf2.appendText("\n"+e.keyCode)
//alt+C
if(e.keyCode==231){
tf2.appendText("\nALT + C")
}
//alt+V
if(e.keyCode==175){
tf2.appendText("\nALT + V")
}
//alt+X
if(e.keyCode==188){
tf2.appendText("\nALT + X")
}
}
When the SWF has focus, you can just listen in actionscript for keypresses. And if you want, you can send them to Javascript as well.
addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
private function onKeyDown(e:KeyboardEvent):void
{
// handle key down,
}