JSXinput.js is made available under the MIT public license.
A copy of the licensing terms can be viewed below and at the beginning of the JSXinput.js file.
Helpful information to know:

JSXinput encapsulates all its variables in an object named _jsxinput.
This frees you to name your variables anything you like, except "_jsxinput".
Also, a bit of advice about Firefox and gamepads:
Firefox's detection of gamepads is less consistent than Chrome's.
If you have connected gamepads and some are not detected by Firefox, I have found that reconnecting them to different USB ports can correct the issue.
Firefox also disables the gamepad entirely when not on https sites.

_jsxinput.init(mappingExitCallback)
The first JSXinput function that you will likely call. This displays the controller mapping menu.
The purpose of the mapping menu is to allow the user to map the gamepad devices presented by the browser's DOM to JSpad objects, which more closely resemble the familiar gamepads we all cherish so.
When the mapping menu is exited, the function passed as the mappingExitCallback parameter is called.
mappingExitCallback is expected to be the function that resumes your game's logic after the player exits the controller mapping menu.
_jsxinput.JSpads[]
This is an array of JSpad objects. One of these will be created for each device that was successfully mapped by the user.
If you are familiar with a typical console game controller, you will likely find most JSpad methods intuitive.
JSpads represent the bulk of JSXinput's functionality and the remainder of this page describes their methods.
JSpad.update()
This updates the JSpad to reflect the current state of the corresponding device in the native DOM properties.
It is expected that this will be called once per game "tic"; likely near the beginning of your game loop.
JSpad button state methods
These methods correspond to a gamepad's button states.
They return either 0, 1, or in the case of analog buttons, a floating point value between 0.0 and 1.0 inclusive.
JSpad.X() - corresponds to the left face button in the conventional diamond arrangement.
JSpad.Y() - corresponds to the top face button in the conventional diamond arrangement.
JSpad.A() - corresponds to the bottom face button in the conventional diamond arrangement.
JSpad.B() - corresponds to the right face button in the conventional diamond arrangement.
JSpad.R1() - corresponds to the right front shoulder button.
JSpad.R2() - corresponds to the right rear shoulder button.
JSpad.R3() - corresponds to the right analog stick when pressed as a button.
JSpad.L1() - corresponds to the left front shoulder button.
JSpad.L2() - corresponds to the left rear shoulder button.
JSpad.L3() - corresponds to the left analog stick when pressed as a button.
JSpad.Start() - corresponds to the face button located to the right of the gamepad's center.
JSpad.Select() - corresponds to the face button located to the left of the gamepad's center.
JSpad previous button state methods
These methods return the state of each button before the last time .update() was called for that button's JSpad.
They are intended to enable convenient detection of new button presses (and releases) by comparing the current button state to the previous button state.
They return either 0, 1, or in the case of analog buttons, a floating point value between 0.0 and 1.0 inclusive.
Since the correspondence between buttons and variable names is explained above, it is not repeated here.
JSpad.Xprev()
JSpad.Yprev()
JSpad.Aprev()
JSpad.Bprev()
JSpad.R1prev()
JSpad.R2prev()
JSpad.R3prev()
JSpad.L1prev()
JSpad.L2prev()
JSpad.L3prev()
JSpad.Startprev()
JSpad.Selectprev()
JSpad button tics methods
These methods return (as an integer) the number of times JSpad.update() has been called on their respective device since the last time the respective button state was zero. They are intended to be used to determine how many "tics" a button has been held.
Since the correspondence between buttons and variable names is explained above, it is not repeated here.
JSpad.Xtics()
JSpad.Ytics()
JSpad.Atics()
JSpad.Btics()
JSpad.R1tics()
JSpad.R2tics()
JSpad.R3tics()
JSpad.L1tics()
JSpad.L2tics()
JSpad.L3tics()
JSpad.Starttics()
JSpad.Selecttics()
JSpad button time methods
These methods return (as an integer) the length of time the respective button has been pressed in milliseconds, or 0 if the button is not pressed.
Since the correspondence between buttons and variable names is explained above, it is not repeated here.
JSpad.Xtime()
JSpad.Ytime()
JSpad.Atime()
JSpad.Btime()
JSpad.R1time()
JSpad.R2time()
JSpad.R3time()
JSpad.L1time()
JSpad.L2time()
JSpad.L3time()
JSpad.Starttime()
JSpad.Selecttime()
JSpad axes state methods
These methods return the axes value of the respective analog stick as a floating point value ranging from -1.0 to 1.0.
They are affected by the anti-drift scan performed in the mapping interface.
JSpad.Lx()
JSpad.Ly()
JSpad.Rx()
JSpad.Ry()
JSpad D-Pad state methods
These methods each return the state of a directional pad's axis as: -1, 0, or 1:
JSpad.dpadX()
JSpad.dpadY()
These methods, like the equivalent for buttons, each return the state of a directional pad's axis prior to the most recent call to JSXinput.update().
Like the methods above, they return -1, 0, or 1.
JSpad.dpadXprev()
JSpad.dpadYprev()
These methods, like the equivalent for buttons, each return the number of times JSXinput.update() has been called since the state of directional pad's axis was zero.
They return integers.
JSpad.dpadXtics()
JSpad.dpadYtics()
These methods, like the equivalent for buttons, each return how long the state of directional pad's axis has been nonzero.
They return the time in milliseconds expressed as an integer.
JSpad.dpadXtime()
JSpad.dpadYtime()
A few words about gamepad events:

JSXinput adds event listeners to the connectpad and disconnectpad events during gamepad mapping (and removes them after). If your application also adds event listeners to those events, to avoid conflicting with the events used by JSXinput, instead of using:
window.addEventListener("myConnectEventFunction", connectpad)
or:
window.addEventListener("myDisconnectEventFunction", disconnectpad)
Use the provided methods:
_jsxinput.addHostConnectpadEventListener("myConnectEventFunction")
and
_jsxinput.addHostDisconnectpadEventListener("myDisconnectEventFunction")
respectively.
Likewise, to remove gamepad events, instead of using:
window.removeEventListener("myConnectEventFunction", connectpad)
or:
window.removeEventListener("myDisconnectEventFunction", disconnectpad)
Use the provided methods:
_jsxinput.removeHostConnectpadEventListener("myConnectEventFunction")
and
_jsxinput.removeHostDisconnectpadEventListener("myDisconnectEventFunction")
respectively.

If you want to support me, the author of JSXinput, I thank you.
Finance my sordid Top Ramen and grilled cheese lifestyle
Help defray development costs by sending bitcoin to the address below.
Perhaps you do not care about the author of JSXinput one bit.
Perhaps you yearn instead for elliptical deadzones or analog stick states expressed as polar coordinates. Donations to the address below will be used to gauge user interest in more exotic features.
32rk4P9DVdCmtAfduVfDFB7DTZAcfqYzsY
 
3HdPsQ9LzAS3x497yYYFj3nvPRScVgmfxj
 
Don't have any bitcoin? Consider using the money you would donate here to obtain some.
It can cost you only what you can afford to donate and could possibly benefit you.
Do you have a question, comment, or feature request? I hope so.
Please send any or all of the above to:

mutiny@ɡmаil.com
 
 

Include "JSXinput" in the subject of your email or I might miss it.
JSXinput users who are also reddit users may commiserate here.
JSXinput is a javascript library that provides more robust gamepad support than browsers provide natively.
Notable features include:
  • JSXinput presents all gamepads consistently. (In the course of developing JSXinput, I have found that even two gamepads of the same make and model can be presented differently by the same browser!)
  • Presents an abstraction of a gamepad, not just a list of axes and buttons.
  • Methods for conveniently tracking gamepad state change.
  • Allows users to map and remap devices.
  • Preserves device mappings in a cookie so users won't need to remap devices unless they want to.
  • Detects and eliminates analog input "drift".
  • Respects computing resources: All UI elements and events are destroyed when not in use.
  • Written in pure javascript without any additional dependencies. Use JSXinput with any javascript libraries you like. Or none at all!
If you make browser games that use or would benefit from gamepad input, JSXinput was made for you.
 
Mapped gamepad detected. Click here for second demo!
-->