符合ARIA的radiogroup

本文详细介绍了一种使用纯JavaScript实现的RadioGroup组件,该组件能够处理键盘导航、焦点管理和ARIA角色设置,以增强HTML元素的可访问性和用户体验。

HTML

<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="main.css">
  </head>
  <body>

    <div class="demo">
      <div>
        <label for="name">Name:</label>
        <input type="text" id="name" name="name">
      </div>

      <h3>Drink Options</h3>

      <ul id="group1" class="radiogroup">
        <li class="radio">
          Water
        </li>
        <li class="radio">
          Tea
        </li>
        <li class="radio">
          Coffee
        </li>
        <li class="radio">
          Cola
        </li>
        <li class="radio">
          Ginger Ale
        </li>
      </ul>

      <div>
        <button>Order a drink</button>
      </div>

    </div>

    <script src="radiogroup.js"></script>

  </body>
</html>

省略css,js是核心,以下为部分核心js代码

  function RadioGroup(id) {
    this.el = document.querySelector(id);
    this.buttons = slice(this.el.querySelectorAll('.radio'));
    this.focusedIdx = 0;
    this.focusedButton = this.buttons[this.focusedIdx];

    this.el.addEventListener('keydown', this.handleKeyDown.bind(this));
    this.el.addEventListener('click', this.handleClick.bind(this));

    // Set ARIA role for the radio group.
    this.el.setAttribute('role', 'radiogroup');

    var firstButton = true;
    for (var button of this.buttons) {
      if (firstButton) {
        button.tabIndex = '0';
        firstButton = false;
      } else {
        button.tabIndex = '-1';
      }
    // Set ARIA role for the radio.
      button.setAttribute('role', 'radio');
    }
  }

上面为radiogroup和radio添加role

RadioGroup.prototype.handleKeyDown = function(e) {
  switch(e.keyCode) {

    case VK_UP:
    case VK_LEFT: {

      e.preventDefault();

      this.focusedIdx--;
      if (this.focusedIdx < 0)
        this.focusedIdx = this.focusedIdx + this.buttons.length;

      break;
    }

    case VK_DOWN:
    case VK_RIGHT: {

      e.preventDefault();

      this.focusedIdx = (this.focusedIdx + 1) % this.buttons.length;

      break;
    }

  case VK_SPACE:
      var focusedButton = e.target;
      var idx = this.buttons.indexOf(focusedButton);
      if (idx < 0)
        return;
      this.focusedIdx = idx;
      break;

    default:
      return;
  }

  this.changeFocus();
};

RadioGroup.prototype.handleClick = function(e) {
  var button = e.target;
  var idx = this.buttons.indexOf(button);
  if (idx < 0)
    return;
  this.focusedIdx = idx;
  this.changeFocus();
};

上为监听器函数

 RadioGroup.prototype.changeFocus = function() {
   // Set the old button to tabindex -1
   this.focusedButton.tabIndex = -1;
   this.focusedButton.removeAttribute('checked');
   this.focusedButton.setAttribute('aria-checked', 'false');

   // Set the new button to tabindex 0 and focus it
   this.focusedButton = this.buttons[this.focusedIdx];
   this.focusedButton.tabIndex = 0;
   this.focusedButton.focus();
   this.focusedButton.setAttribute('checked', '');
   this.focusedButton.setAttribute('aria-checked', 'true');
 };

 var group1 = new RadioGroup('#group1');

}());

aria-checked这个属性不用初始化,可以在焦点改变时修改

通过cypress在html中先判断是否为主编区域的是否区域是否可点击,如果可点击选择是,否则不操作 <div data-v-40a08c01="" class="el-col el-col-8 is-guttered" style="padding-right: 10px; padding-left: 10px;"><div data-v-40a08c01="" class="el-form-item el-form-item--default is-success asterisk-left el-form-item--label-right" role="group" aria-labelledby="el-id-9628-347"><div class="el-form-item__label-wrap" style="margin-left: 73px;"><div id="el-id-9628-347" class="el-form-item__label" style="width: auto;">是否为主编</div></div><div class="el-form-item__content"><div class="el-tooltip__trigger" style="width: 100%;"><div data-v-40a08c01="" class="flex"><div data-v-40a08c01="" class="el-radio-group" role="radiogroup" show-word-limit="false" clearable="true" options="[object Object],[object Object]" id="el-id-9628-468" aria-label="radio-group" placeholder=""><div data-v-40a08c01="" class="el-radio-group" role="radiogroup" id="el-id-9628-467" aria-label="radio-group"><label data-v-40a08c01="" class="el-radio is-disabled el-radio--default" timeouthidden="false" attribute1="" attribute5="success" attribute9="0" associateddicttype="RESEARCH_PROJECT_SOURCE_LEVEL_STANDARD"><span class="el-radio__input is-disabled"><input class="el-radio__original" name="el-id-9628-350" type="radio" value="Y" tabindex="0" disabled=""><span class="el-radio__inner"></span></span><span class="el-radio__label">是</span></label><label data-v-40a08c01="" class="el-radio is-disabled el-radio--default" timeouthidden="false" attribute1="" attribute5="warning" attribute9="1" associateddicttype="RESEARCH_PROJECT_SOURCE_LEVEL_NON_STANDARD"><span class="el-radio__input is-disabled"><input class="el-radio__original" name="el-id-9628-350" type="radio" value="N" disabled=""><span class="el-radio__inner"></span></span><span class="el-radio__label">否</span></label></div></div></div></div></div></div></div>
07-14
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值