views:

1036

answers:

4

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?

+1  A: 

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.

Theo.T
+2  A: 

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

evilpenguin
Thanks e-peng. Is there a way to get your demo to work when flash has focus? (would like to first handle all keyboard events in javascript, then delegate how I would like them handled.)
jedierikb
When the flash has focus, you must treat the events in flash first, by addEventListener(KeyboardEvent.KEY_DOWN, ...) and then send them to JavaScript. I don't think you can intercept them first in JavaScript...
evilpenguin
A: 

Nice Theo.T

Unfortunaly it stopped working when the .swf got focus...

Moose
A: 

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")
    }
}
Moose