Gamepad API

var haveEvents = 'ongamepadconnected' in window; var controllers = {}; function connecthandler(e) { addgamepad(e.gamepad); } function addgamepad(gamepad) { controllers[gamepad.index] = gamepad; var d = document.createElement("div"); d.setAttribute("id", "controller" + gamepad.index); var t = document.createElement("h1"); t.appendChild(document.createTextNode("gamepad: " + gamepad.id)); d.appendChild(t); var b = document.createElement("div"); b.className = "buttons"; for (var i = 0; i < gamepad.buttons.length; i++) { var e = document.createElement("span"); e.className = "button"; //e.id = "b" + i; e.innerHTML = i; b.appendChild(e); } d.appendChild(b); var a = document.createElement("div"); a.className = "axes"; for (var j = 0; j < gamepad.axes.length; j++) { var p = document.createElement("progress"); p.className = "axis"; //p.id = "a" + j; p.setAttribute("max", "2"); p.setAttribute("value", "1"); p.innerHTML = j; a.appendChild(p); } d.appendChild(a); // See https://github.com/luser/gamepadtest/blob/master/index.html var start = document.getElementById("start"); if (start) { start.style.display = "none"; } document.body.appendChild(d); requestAnimationFrame(updateStatus); } function disconnecthandler(e) { removegamepad(e.gamepad); } function removegamepad(gamepad) { var d = document.getElementById("controller" + gamepad.index); document.body.removeChild(d); delete controllers[gamepad.index]; } function updateStatus() { if (!haveEvents) { scangamepads(); } var i = 0; var j; for (j in controllers) { var controller = controllers[j]; var d = document.getElementById("controller" + j); var buttons = d.getElementsByClassName("button"); for (i = 0; i < controller.buttons.length; i++) { var b = buttons[i]; var val = controller.buttons[i]; var pressed = val == 1.0; if (typeof(val) == "object") { pressed = val.pressed; val = val.value; } var pct = Math.round(val * 100) + "%"; b.style.backgroundSize = pct + " " + pct; if (pressed) { b.className = "button pressed"; } else { b.className = "button"; } } var axes = d.getElementsByClassName("axis"); for (i = 0; i < controller.axes.length; i++) { var a = axes[i]; a.innerHTML = i + ": " + controller.axes[i].toFixed(4); a.setAttribute("value", controller.axes[i] + 1); } } requestAnimationFrame(updateStatus); } function scangamepads() { var gamepads = navigator.getGamepads ? navigator.getGamepads() : (navigator.webkitGetGamepads ? navigator.webkitGetGamepads() : []); for (var i = 0; i < gamepads.length; i++) { if (gamepads[i]) { if (gamepads[i].index in controllers) { controllers[gamepads[i].index] = gamepads[i]; } else { addgamepad(gamepads[i]); } } } } window.addEventListener("gamepadconnected", connecthandler); window.addEventListener("gamepaddisconnected", disconnecthandler); if (!haveEvents) { setInterval(scangamepads, 500); }

3 Responses

I think the lint warning in line 33 is correct here, in that the variable i is hoisted to the top of the function "addgamepad", even though the same has happened already in line 20.

It's not creating an issue here as you're re-assigning the variable after its first usage has ended, but it would probably be good practice to choose something else here.
@Patrick Metzdorf Actually, you are right! I had not seen the lint warning.

This would be standard practice for me, as the "scope" of the first instance of i is only limited to that for loop, and thus leaves the opportunity to reuse the same variable name. I would consider it bad practice to just reuse the variable without defining it again (which is the actual complaint of the lint warning), so I'll just name the second variable differently.

Cheers, mate!
@Yarmo Mackenbach Yea it's one of those Javascript oddities: ES5's "var" doesn't use block scoping (i.e. the variable is not scoped to the loop, but to the function it resides in). However, changing this to ES6 (e.g. with Babel), you could use "let" instead, which is indeed block-scoped.

Write a comment

You can use [html][/html], [css][/css], [php][/php] and more to embed the code. Urls are automatically hyperlinked. Line breaks and paragraphs are automatically generated.