keycharm.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. "use strict";
  2. /**
  3. * Created by Alex on 11/6/2014.
  4. */
  5. // https://github.com/umdjs/umd/blob/master/returnExports.js#L40-L60
  6. // if the module has no dependencies, the above pattern can be simplified to
  7. (function (root, factory) {
  8. if (typeof define === 'function' && define.amd) {
  9. // AMD. Register as an anonymous module.
  10. define([], factory);
  11. } else if (typeof exports === 'object') {
  12. // Node. Does not work with strict CommonJS, but
  13. // only CommonJS-like environments that support module.exports,
  14. // like Node.
  15. module.exports = factory();
  16. } else {
  17. // Browser globals (root is window)
  18. root.keycharm = factory();
  19. }
  20. }(this, function () {
  21. function keycharm(options) {
  22. var preventDefault = options && options.preventDefault || false;
  23. var container = options && options.container || window;
  24. var _exportFunctions = {};
  25. var _bound = {keydown:{}, keyup:{}};
  26. var _keys = {};
  27. var i;
  28. // a - z
  29. for (i = 97; i <= 122; i++) {_keys[String.fromCharCode(i)] = {code:65 + (i - 97), shift: false};}
  30. // A - Z
  31. for (i = 65; i <= 90; i++) {_keys[String.fromCharCode(i)] = {code:i, shift: true};}
  32. // 0 - 9
  33. for (i = 0; i <= 9; i++) {_keys['' + i] = {code:48 + i, shift: false};}
  34. // F1 - F12
  35. for (i = 1; i <= 12; i++) {_keys['F' + i] = {code:111 + i, shift: false};}
  36. // num0 - num9
  37. for (i = 0; i <= 9; i++) {_keys['num' + i] = {code:96 + i, shift: false};}
  38. // numpad misc
  39. _keys['num*'] = {code:106, shift: false};
  40. _keys['num+'] = {code:107, shift: false};
  41. _keys['num-'] = {code:109, shift: false};
  42. _keys['num/'] = {code:111, shift: false};
  43. _keys['num.'] = {code:110, shift: false};
  44. // arrows
  45. _keys['left'] = {code:37, shift: false};
  46. _keys['up'] = {code:38, shift: false};
  47. _keys['right'] = {code:39, shift: false};
  48. _keys['down'] = {code:40, shift: false};
  49. // extra keys
  50. _keys['space'] = {code:32, shift: false};
  51. _keys['enter'] = {code:13, shift: false};
  52. _keys['shift'] = {code:16, shift: undefined};
  53. _keys['esc'] = {code:27, shift: false};
  54. _keys['backspace'] = {code:8, shift: false};
  55. _keys['tab'] = {code:9, shift: false};
  56. _keys['ctrl'] = {code:17, shift: false};
  57. _keys['alt'] = {code:18, shift: false};
  58. _keys['delete'] = {code:46, shift: false};
  59. _keys['pageup'] = {code:33, shift: false};
  60. _keys['pagedown'] = {code:34, shift: false};
  61. // symbols
  62. _keys['='] = {code:187, shift: false};
  63. _keys['-'] = {code:189, shift: false};
  64. _keys[']'] = {code:221, shift: false};
  65. _keys['['] = {code:219, shift: false};
  66. var down = function(event) {handleEvent(event,'keydown');};
  67. var up = function(event) {handleEvent(event,'keyup');};
  68. // handle the actualy bound key with the event
  69. var handleEvent = function(event,type) {
  70. if (_bound[type][event.keyCode] !== undefined) {
  71. var bound = _bound[type][event.keyCode];
  72. for (var i = 0; i < bound.length; i++) {
  73. if (bound[i].shift === undefined) {
  74. bound[i].fn(event);
  75. }
  76. else if (bound[i].shift == true && event.shiftKey == true) {
  77. bound[i].fn(event);
  78. }
  79. else if (bound[i].shift == false && event.shiftKey == false) {
  80. bound[i].fn(event);
  81. }
  82. }
  83. if (preventDefault == true) {
  84. event.preventDefault();
  85. }
  86. }
  87. };
  88. // bind a key to a callback
  89. _exportFunctions.bind = function(key, callback, type) {
  90. if (type === undefined) {
  91. type = 'keydown';
  92. }
  93. if (_keys[key] === undefined) {
  94. throw new Error("unsupported key: " + key);
  95. }
  96. if (_bound[type][_keys[key].code] === undefined) {
  97. _bound[type][_keys[key].code] = [];
  98. }
  99. _bound[type][_keys[key].code].push({fn:callback, shift:_keys[key].shift});
  100. };
  101. // bind all keys to a call back (demo purposes)
  102. _exportFunctions.bindAll = function(callback, type) {
  103. if (type === undefined) {
  104. type = 'keydown';
  105. }
  106. for (var key in _keys) {
  107. if (_keys.hasOwnProperty(key)) {
  108. _exportFunctions.bind(key,callback,type);
  109. }
  110. }
  111. };
  112. // get the key label from an event
  113. _exportFunctions.getKey = function(event) {
  114. for (var key in _keys) {
  115. if (_keys.hasOwnProperty(key)) {
  116. if (event.shiftKey == true && _keys[key].shift == true && event.keyCode == _keys[key].code) {
  117. return key;
  118. }
  119. else if (event.shiftKey == false && _keys[key].shift == false && event.keyCode == _keys[key].code) {
  120. return key;
  121. }
  122. else if (event.keyCode == _keys[key].code && key == 'shift') {
  123. return key;
  124. }
  125. }
  126. }
  127. return "unknown key, currently not supported";
  128. };
  129. // unbind either a specific callback from a key or all of them (by leaving callback undefined)
  130. _exportFunctions.unbind = function(key, callback, type) {
  131. if (type === undefined) {
  132. type = 'keydown';
  133. }
  134. if (_keys[key] === undefined) {
  135. throw new Error("unsupported key: " + key);
  136. }
  137. if (callback !== undefined) {
  138. var newBindings = [];
  139. var bound = _bound[type][_keys[key].code];
  140. if (bound !== undefined) {
  141. for (var i = 0; i < bound.length; i++) {
  142. if (!(bound[i].fn == callback && bound[i].shift == _keys[key].shift)) {
  143. newBindings.push(_bound[type][_keys[key].code][i]);
  144. }
  145. }
  146. }
  147. _bound[type][_keys[key].code] = newBindings;
  148. }
  149. else {
  150. _bound[type][_keys[key].code] = [];
  151. }
  152. };
  153. // reset all bound variables.
  154. _exportFunctions.reset = function() {
  155. _bound = {keydown:{}, keyup:{}};
  156. };
  157. // unbind all listeners and reset all variables.
  158. _exportFunctions.destroy = function() {
  159. _bound = {keydown:{}, keyup:{}};
  160. container.removeEventListener('keydown', down, true);
  161. container.removeEventListener('keyup', up, true);
  162. };
  163. // create listeners.
  164. container.addEventListener('keydown',down,true);
  165. container.addEventListener('keyup',up,true);
  166. // return the public functions.
  167. return _exportFunctions;
  168. }
  169. return keycharm;
  170. }));