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插件,但是很容易。请参考:
使用 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>
截图如下:
使用 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 中完美运行。
希望这对偶然发现这个的人有所帮助。
我一直在玩 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插件,但是很容易。请参考:
使用 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>
截图如下:
使用 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 中完美运行。 希望这对偶然发现这个的人有所帮助。