使 select 元素真正无法聚焦

Make select element truly unfocusable

我一直在尝试使 select 元素无法聚焦。多个来源建议将 tabIndex 设置为 -1。这就是我尝试过的,但失败了。

考虑以下示例:

function addEv(id, event, message)
{
  document.getElementById(id).addEventListener(event, function(){
    document.getElementById('console').innerHTML = message;
  });
}
addEv('select', 'focus', 'select focus');
addEv('select', 'blur', 'select blur');

addEv('span', 'focus', 'span focus');
addEv('span', 'blur', 'span blur');

addEv('select-wrapper', 'focus', 'div focus');
addEv('select-wrapper', 'blur', 'div blur');
#select-wrapper {
  display: inline-block;
  padding: 1px;
  border: 1px solid transparent;
}
#select-wrapper:focus {
  border: 1px solid;
  border-radius: 5px;
  outline: none;
}
<input type="text" value="3 glasses">
<div id="select-wrapper" tabindex="0">
  <span id="span">of</span>
  <select id="select" tabindex="-1">
    <option value="beer">Beer</option>
    <option value="wine" selected>Wine</option>
    <option value="vodka">Vodka</option>
  </select>
</div>
<input type="button" value="drink">
<div id="console"></div><br>

如果您在元素中切换,一切都会按预期进行。两个输入元素和 div 元素获得焦点。单击显示 "of" 的跨度也是如此。但是,如果您单击 select 元素,它将获得焦点,而不是 div。这意味着错误的焦点事件被触发并且 select 元素的视觉效果在它被聚焦时发生变化。这在 Firefox 和 Chrome 中是一致的,所以我认为这是故意的。

问题是:如何使 select 元素不可聚焦,而使它周围的 div 元素可聚焦?当然,我仍然希望能够打开下拉菜单和 select 一个选项。

EDIT: This method stopped working in Firefox 52 or some earlier version

我自己找到了一个肮脏的解决方案。如果我忽略 select 元素仍然触发焦点和模糊事件的事实,我可以通过执行 select.blur()div.focus() 使它看起来像 div 元素变得聚焦 select 元素获得焦点。请参阅下面的代码。

注意:如果您要使用我的解决方案,请不要忘记手动实现辅助功能,因为正如@nnnnnn 指出的那样,它们将不再起作用。

function addEv(id, event, message)
{
 document.getElementById(id).addEventListener(event, function(){
    document.getElementById('console').innerHTML += message+"<br>";
  });
}
addEv('select', 'focus', 'select focus');
addEv('select', 'blur', 'select blur');

addEv('span', 'focus', 'span focus');
addEv('span', 'blur', 'span blur');

addEv('select-wrapper', 'focus', 'div focus');
addEv('select-wrapper', 'blur', 'div blur');

document.getElementById('select').addEventListener('focus', function(){
 document.getElementById('select').blur();
  document.getElementById('select-wrapper').focus();
});
#select-wrapper {
  display: inline-block;
  padding: 1px;
  border: 1px solid transparent;
}
#select-wrapper:focus {
  border: 1px solid;
  border-radius: 5px;
  outline: none;
}
<input type="text" value="3 glasses">
<div id="select-wrapper" tabindex="0">
  <span id="span">of</span>
  <select id="select" tabindex="-1">
    <option value="beer">Beer</option>
    <option value="wine" selected>Wine</option>
    <option value="vodka">Vodka</option>
  </select>
</div>
<input type="button" value="drink">
<div id="console"></div><br>

除了tabindex=-1之外,还可以把这个加到CSS属性.

  pointer-events: none;

这对我有用