JavaScript: Firefox Nightly introduces DOM Joystick Events

Late last week, excitement buzzed here at Bocoup, when David Humphrey of Mozilla dropped us a line with links to a Firefox nightly build that had added rudimentary support for a set of DOM Joystick events. Several hours later we, along with Jason Orendorff and TedMielczarek of Mozilla, put together a couple of prototype experiments to demonstrate potential use-cases for the new event types. Additionally, we started thinking and planning an approach for authoring a JS library in conjunction with the emerging API.

Currently, Mozilla wiki page for the Joystick API specifies three new event types allow you to subscribe to joystick events such as button up/down and joystick move:

  • MozJoyButtonDown
  • MozJoyButtonUp
  • MozJoyAxisMove

All three events share a JoystickID property that is unique per connected device (allowing multiple devices).

The MozJoyButtonUp and MozJoyButtonDown events also contain a button property corresponding to the button being pressed or released. Each button on the controller will have a unique ID assigned to it.

The MozJoyAxisMove event is triggered on analog sticks move and has the following unique properties:

  • axis – an integer indicating which axis the analog stick is being moved on. Note that an axis is not just from the analog stick’s neutral position to an edge but rather from edge to edge. Depending on the manufacturer, the number of axes can vary. For example, the XBox wired controller has 4 axes (top to bottom, left to right, and two diagonals.)
  • value – The position of the analog stick on the axis it’s on. The value is somewhere between -1.0 and 1.0.

The following gist can be used to analyze the output of the above three events:


var joyEvents = {

    MozJoyAxisMove: {
      props: [ "joystickID", "axis", "value" ],
      listen: 1
    MozJoyButtonUp: {
      props: [ "joystickID", "button" ],
      listen: 1
    MozJoyButtonDown: {
      props: [ "joystickID", "button" ],
      listen: 1
  joyEventsKeys = Object.keys( joyEvents );

// Iterate joystick events, add an event listener to the window to log events
joyEventsKeys.forEach(function( type, idx ) {

  var joyEvent = joyEvents[ type ];

  if ( joyEvent.listen ) {

    window.addEventListener( type, function( event ) {

        type, val ) {
          return val + ": " + event[ val ];
        }).join(", ")

    }, false);

  if ( idx === joyEventsKeys.length - 1 ) {
    console.log( "MozJoy* Events Ready" );
}, joyEvents );

Our first prototype can be found here: It allows you to control video playback with your controller. The second prototype uses Paper.js and simply allows you to move a dot across the screen using your analog stick. If you have an XBox controller you can grab the FireFox nightly build containing the event support here: Firefox 8 Nightly (Special builds) and if you are on the Mac you can get XBox controller drivers here: XBox 360 OSX Drivers.

If you don’t want to go through all of the setup, check out the video demo here:

During our brief experiments we came across a few initial issues such as the high number of events being fired. At the moment the event buffer can get overloaded pretty quickly especially when the analog stick is maxed out on an axis. Keeping the number of events high is obviously important to achieve the kind of precision we see in console games. Additionally, the diversity of controllers will ensure that single button to action mappings will be challenging to accomplish. These issues and others are ones we hope to address in some future work on Joystick.js.

The introduction of joystick events in the browser marks a milestone in the history of the web and specifically the role it plays in our everyday entertainment demands and how we interact with that experience.

Note: The Firefox 8 build is actually a “Try Server” build – not a “Nightly” as the url and title imply.


We moved off of Disqus for data privacy and consent concerns, and are currently searching for a new commenting tool.

  1. Don’t most games poll the controller state in a loop, rather than responding to events? It seems like that would be better than spamming events all the time.

  2. Hey, can you provide more detail on the performance issues you’ve encountered, either via e-mail or a comment on the tracking bug? ( https://bugzilla.mozilla.or… ) I’m kind of surprised to see performance issues as bad as the ones you describe for only a single connected controller. If you can provide a way to reproduce the issue I’d be glad to look into it.

  3. Just to clarify, this is an experimental patch, and hasn’t landed yet.

    Hat events are mapped as axis events on most platforms, but sometimes button events (depending on the controller and platform).

    Polling has been discussed, and I’m looking to modify the API to allow a form of polling, but it doesn’t fit very well with the web style of development.

  4. I’m not seeing any mention of dual analog inputs, nor analog button inputs (i.e. triggers).

    Cover the above, and (combined with the accelerometer API) all current gaming input methods should be supportable.

    Kinect and PSMove support could be added via the webcam API, whenever that hits.

Contact Us

We'd love to hear from you. Get in touch!


P.O. Box 961436
Boston, MA 02196