首页 > 解决方案 > 使 Select2 药盒控件更易于访问且合规并需要反馈(带上您的屏幕阅读器)

问题描述

我正在寻找有关以下代码/示例的屏幕阅读器改进的反馈。

Select2 药盒控件需要更易于访问。他们在这个主题Select2 问题页面上有一个未解决的问题,在我收到更多反馈后,他们会向他们提交更改建议(或提交带有更改的分支)。

以下代码中的我的目标是:

  1. 开始到结束体验
  2. 当用户第一次开始控制时,它需要读出加载哪些项目是选择的。搜索框输入在最后
  3. 并造成混乱,将使用 ROLE 来改变这一点。
  4. 给用户 1 种简单的方法来删除项目或所有选定的项目 屏幕阅读器隐藏个别删除,太多的混乱导致有很多方法来做到这一点。
  5. 选择输入时,会给出明确的使用说明(过滤器列表、打开列表、如何导航)
  6. 当动态生成的可用项目打开并且用户浏览它们时,告诉他们选择了什么和没有选择什么。一个。仔细检查 Aria 标签的使用情况。湾。告诉用户他们可以选择和取消选择项目

我的工作示例在fiddlejs 上

这里还有一份工作副本

//- nonoandy
$(document).ready(function() {
  //this probobly can be done wiht adapters or smarter ways that will take me a lot longer to do lol. -nonoandy

  //using this class like a flag to stop circuler reference
  var updatedHtmlClass = "select2-skipme";

  //init the select2 control
  var select2Orginal = $(".select2Control");
  select2Orginal.select2();

  //find the real select2 control
  var select2Control = $(".select2Control").next();

  //When screen reader user is arrowing through page (not tabbing through) this will explain the UL
  var select2UlDesc = select2Control.find("span.select2-selection");
  select2UlDesc.prepend("<span class='sr-only'>Selected Items</span>");

  //1. Change the role of the <li> that contains the SearchBox, so screen reader count and reading is more accurate. 
  //2. Warning! I would like to move the SearchBox out of the <UL> and the remove all BUT Select2 doesnt' work right if you move it (change to div would be best too)
  var searchBoxLi = select2Control.find("li.select2-search");
  var searchBoxInput = select2Control.find("input.select2-search__field");
  if (searchBoxLi) {
    //making sure screen reader treat the searchbox <li> as a item
    searchBoxLi.attr("role", "search");

    //adding in flag for future skips
    searchBoxLi.addClass(updatedHtmlClass);
    var searchBoxInput = select2Control.find("input.select2-search__field");
    if (searchBoxInput) {
      //adding in screen reader description to help explain purpose of search box
      var searchDescId = select2Orginal.id + "_SearchBox_desc";
      searchBoxInput.attr("aria-describedby", searchDescId);
      searchBoxLi.append("<div id='" + searchDescId + "' class='sr-only'>Optionally you can type to filter and after activating press Up or Down arrows to select or unselect items</div>")
    }
  }

  //Not tested Yet
  //This <span> is inside the <ul> which isn't good syntax but doens't seem to mess with JAWS screen readers
  var clearAllSpan = select2Control.find("span.select2-selection__clear");
  if (clearAllSpan) {
    clearAllSpan.text("<i class='fas fa-times' aria-hidden='true'></i><span class='sr-only'>Remove all items</span>");
  }

  //When a <li> is added after selection, we need to do a few things
  //1. Update the remove <span> with icon because I like that better
  //2. Aria Hide the  remove-span and leave just selected text for screen readers to find.
  //				WHY!! because they can select and unselect in the dropdown and there is a "remove all" option.  Adding too much stuff makes it confusing. (less is more)
  //3. add class-flags in because circular referenes 
  var selectUl = select2Control.find("ul.select2-selection__rendered");
  $(selectUl).on('DOMNodeInserted', 'li', function(e) {
    //need "Hooks" or events for custom code when a <li> is added
    //DOMNodeInserted is old but faster to uses than MutationObserver #ClearnUp
    if (e.currentTarget.className.indexOf(updatedHtmlClass) == -1) {
      e.currentTarget.className += " " + updatedHtmlClass;
      var newRemoveItemHtml = "<span aria-hidden='true' class='select2-selection__choice__remove' role='presentation' title='Remove " + e.currentTarget.title + "'><i class='fas fa-times'></i></span>" + e.currentTarget.title;
      if (e.currentTarget.innerHTML.indexOf(updatedHtmlClass) == -1) {
        e.currentTarget.innerHTML = newRemoveItemHtml;
      }
    }
  });


  //Select2 dynamically shows a dropdown for selecting or unselecting items
  //I want to make sure this list of items is clearly marked as 'Selected' or 'Not Selected' 
  $('select').on('select2:open', function(e) {
    var dynamixULId = "#" + select2Control.find(".select2-selection").attr("aria-owns");
    $(dynamixULId).on('DOMNodeInserted', 'li', function(e) {
      //AGAIN! need "Hooks" or events for custom code when a <li> is added
      //DOMNodeInserted is old but faster to uses than MutationObserver #ClearnUp
      var currentLi = $(e.currentTarget);

      //it seems the aria-selected is changed after the controls are loaded, so I need a even to trigger and update screen reader text too.
      //attrchange is a older extention there could be better ways of doing this #ResearchLater 
      $(currentLi).attrchange({
        trackValues: true,
        callback: function(event) {
          if (event.attributeName == "aria-selected") {
            if (!currentLi.attr("data-select2-data")) {
              currentLi.attr("data-select2-data", currentLi.text())
            }
            //the aria-selected will make the screen reader say "not selected"
            currentLi.html("<span class='sr-only'>" +
              ((event.newValue == "true") ? "Selected" : "") +
              "</span>" +
              currentLi.attr("data-select2-data"));
          }
        }
      });
    });
  });
});
body {
  /* background: #20262E;*/
  padding: 30px;
  font-family: Helvetica;
}
.select2-results__option[aria-selected="true"]:before {
    content: '\f14a';
    font-family: "Font Awesome 5 Free";
    font-weight: 600;
    padding-right:5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/attrchange/2.0.1/attrchange.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/css/all.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/select2@4.0.13/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/select2@4.0.13/dist/js/select2.min.js"></script>



<div id="banner-message">
  <h1>Making the Select2 control more accessible!</h1>
</div>

<div class="form-group">
  <label for="select2Control">
 Pick People 
</label>
  <select id="select2Control" class="select2Control form-control" name="things[]" multiple="multiple">
    <option value="1">Andy</option>
    <option value="2">Bob</option>
    <option value="3">Russ</option>
    <option value="4">Dave</option>
    <option value="5">Matt</option>
    <option value="6">Adam</option>
  </select>
</div>

标签: jqueryaccessibilityjquery-select2screen-readersmutation-observers

解决方案


这个问题已经过时,因为 Select2 产品已更新以更好地处理可访问性。

我的建议是,确保拥有该产品的最新版本。


推荐阅读