aria-utils.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. 'use strict';
  2. exports.__esModule = true;
  3. var aria = aria || {};
  4. aria.Utils = aria.Utils || {};
  5. /**
  6. * @desc Set focus on descendant nodes until the first focusable element is
  7. * found.
  8. * @param element
  9. * DOM node for which to find the first focusable descendant.
  10. * @returns
  11. * true if a focusable element is found and focus is set.
  12. */
  13. aria.Utils.focusFirstDescendant = function (element) {
  14. for (var i = 0; i < element.childNodes.length; i++) {
  15. var child = element.childNodes[i];
  16. if (aria.Utils.attemptFocus(child) || aria.Utils.focusFirstDescendant(child)) {
  17. return true;
  18. }
  19. }
  20. return false;
  21. };
  22. /**
  23. * @desc Find the last descendant node that is focusable.
  24. * @param element
  25. * DOM node for which to find the last focusable descendant.
  26. * @returns
  27. * true if a focusable element is found and focus is set.
  28. */
  29. aria.Utils.focusLastDescendant = function (element) {
  30. for (var i = element.childNodes.length - 1; i >= 0; i--) {
  31. var child = element.childNodes[i];
  32. if (aria.Utils.attemptFocus(child) || aria.Utils.focusLastDescendant(child)) {
  33. return true;
  34. }
  35. }
  36. return false;
  37. };
  38. /**
  39. * @desc Set Attempt to set focus on the current node.
  40. * @param element
  41. * The node to attempt to focus on.
  42. * @returns
  43. * true if element is focused.
  44. */
  45. aria.Utils.attemptFocus = function (element) {
  46. if (!aria.Utils.isFocusable(element)) {
  47. return false;
  48. }
  49. aria.Utils.IgnoreUtilFocusChanges = true;
  50. try {
  51. element.focus();
  52. } catch (e) {}
  53. aria.Utils.IgnoreUtilFocusChanges = false;
  54. return document.activeElement === element;
  55. };
  56. aria.Utils.isFocusable = function (element) {
  57. if (element.tabIndex > 0 || element.tabIndex === 0 && element.getAttribute('tabIndex') !== null) {
  58. return true;
  59. }
  60. if (element.disabled) {
  61. return false;
  62. }
  63. switch (element.nodeName) {
  64. case 'A':
  65. return !!element.href && element.rel !== 'ignore';
  66. case 'INPUT':
  67. return element.type !== 'hidden' && element.type !== 'file';
  68. case 'BUTTON':
  69. case 'SELECT':
  70. case 'TEXTAREA':
  71. return true;
  72. default:
  73. return false;
  74. }
  75. };
  76. /**
  77. * 触发一个事件
  78. * mouseenter, mouseleave, mouseover, keyup, change, click 等
  79. * @param {Element} elm
  80. * @param {String} name
  81. * @param {*} opts
  82. */
  83. aria.Utils.triggerEvent = function (elm, name) {
  84. var eventName = void 0;
  85. if (/^mouse|click/.test(name)) {
  86. eventName = 'MouseEvents';
  87. } else if (/^key/.test(name)) {
  88. eventName = 'KeyboardEvent';
  89. } else {
  90. eventName = 'HTMLEvents';
  91. }
  92. var evt = document.createEvent(eventName);
  93. for (var _len = arguments.length, opts = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
  94. opts[_key - 2] = arguments[_key];
  95. }
  96. evt.initEvent.apply(evt, [name].concat(opts));
  97. elm.dispatchEvent ? elm.dispatchEvent(evt) : elm.fireEvent('on' + name, evt);
  98. return elm;
  99. };
  100. aria.Utils.keys = {
  101. tab: 9,
  102. enter: 13,
  103. space: 32,
  104. left: 37,
  105. up: 38,
  106. right: 39,
  107. down: 40,
  108. esc: 27
  109. };
  110. exports.default = aria.Utils;