Internet Explorer 中的多 Select 无法 select 选项

Multi-Select Unable to select option in Internet Explorer

我一直在玩 multi-select 的可访问版本,它具有所有需要的功能,可以与屏幕阅读器等一起使用。我在这里得到了原始版本:https://unfetteredthoughts.net/slides/technica11y/select.html

我对它做了一些修改,主要是使用 Babel 将其转换为 ES5,以便它可以与 IE 一起使用。现在它在 Chrome 中工作得很好,但是在 IE 中它显示正确但是当你打开菜单到 select 一个选项时,如果你点击一个或使用箭头键访问它,菜单关闭没有 select 任何东西,然后将注意力集中在菜单上。它似乎没有抛出任何错误,我不确定为什么会这样。

这里是我开发的版本:https://jsfiddle.net/p0ay7cr5/

如果您在 Chrome 中测试它,它会按预期工作,但在 IE 中,如果您单击一个选项,或按向下箭头浏览它们,它会失败。

我认为问题出在keydown函数上:

var onKeydown = function onKeydown(event) {
  var target = event.target;
  var key = event.key.replace('Arrow', '');
  var list = this;
  var options = Array.from(list.querySelectorAll('[role="option"]'));
  var index = options.indexOf(target);
  switch (key) {
    case 'Up':
      event.preventDefault();
      if (index > 0) {
        options[index -= 1].focus();
      }

      break;

    case 'Down':
      event.preventDefault();
      console.log("DownPressed");
      if (index !== options.length - 1) {
          console.log("In if for down");
          console.log(options[index + 1]);
          options[index += 1].focus();
          console.log("after focus");
          $('[id="directorsApprovalSearchForm:siteName"]').focus();
      }

      break;

    case ' ':
    case 'Spacebar':
      /* Selection made */
      console.log("SpacePressed");
      if (!target.hasAttribute('aria-disabled')) {
        event.preventDefault();
        onSelect(event);
      }

      break;

    case 'Home':
      event.preventDefault();
      options[0].focus();
      break;

    case 'End':
      event.preventDefault();
      options[options.length - 1].focus();
      break;

    case 'Esc':
    case 'Escape':
    case 'Tab':
      /* Hide list */
      event.preventDefault();
      hideList(list);
      break;

    default:
      /* Type ahead */
      // Do any of the items start with the character? Easy out
      if (options.some(function (option) {
        return findMatch(key, option);
      })) {
        // Find out if an item is already focused
        var focused = options.indexOf(document.activeElement);
        var next; // Nothing focused, start from the top

        if (focused === -1) {
          next = options.findIndex(function (option) {
            return findMatch(key, option);
          });
        } else {
          var start = focused += 1;
          var items = [].concat(options.slice(start), options.slice(0, start));
          next = options.indexOf(items.find(function (item) {
            return findMatch(key, item);
          }));
        } // Found something


        if (next !== -1) {
          options[next].focus();
        }
      }

      break;
  }
};

在你的代码中设置了一些调试器后,似乎当 select 选项时,它不会触发 onSelect 或 onkeydown 事件,它只是触发 hideList 函数隐藏 select 选项.创建新列表项并附加到网页后,我们需要将事件附加到每个 select 选项。

根据你的描述,你想创建一个多select控件,我建议你可以参考下面的示例,它会使用一些JQuery插件,但是很容易。请参考:

  1. 使用 jQuery MultiSelect 插件。

    <script src="Scripts/multiselect/jquery.min.js"></script>
    <link href="Scripts/multiselect/jquery.multiselect.css" rel="stylesheet" />
    <script src="Scripts/multiselect/jquery.multiselect.js"></script>
    <script>
        $(function () {
            $('#langOpt').multiselect({ columns: 1, placeholder: 'Select Languages', search: true });
        });
    </script>
    <select name="langOpt[]" multiple id="langOpt">
        <option value="C++">C++</option>
        <option value="C#">C#</option>
        <option value="Java">Java</option>
        <option value="Objective-C">Objective-C</option>
        <option value="JavaScript">JavaScript</option>
        <option value="Perl">Perl</option>
        <option value="PHP">PHP</option>
        <option value="Ruby on Rails">Ruby on Rails</option>
        <option value="Android">Android</option>
        <option value="iOS">iOS</option>
        <option value="HTML">HTML</option>
        <option value="XML">XML</option>
    </select>
    

    截图如下:

  2. 使用 bootstrap select 插件。

    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.1/css/bootstrap-select.css" />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.bundle.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.1/js/bootstrap-select.min.js"></script>
    <select class="selectpicker" multiple data-live-search="true">
        <option>Mustard</option>
        <option>Ketchup</option>
        <option>Relish</option>
    </select>
    

    输出如下:

我实际上设法弄清楚了问题所在。在 IE 中,它正在调用 onBlur 方法,该方法聚焦于 multi select 并关闭它。注释掉这些部分后:

list.addEventListener('blur', onBlur);

list.removeEventListener('blur', onBlur);

select 在 Chrome 和 IE 中完美运行。 希望这对偶然发现这个的人有所帮助。