为什么 select 在具有价值的输入上会触发铬中的两个事件?

Why does select on input with value fire two events in chromium?

我正在用 chromium 43 测试这个。

当我按下 select 按钮时,以下代码仅触发 一个事件

<script>
    window.addEventListener('select', function(ev) {
        console.log(ev, ev.timeStamp);
    });
</script>
<input type="text"><button onclick="document.querySelector('input').select()">select</button>

但是,如果我向输入类型=文本添加一个值,我会得到 两个事件,事件之间唯一发生变化的是时间戳 属性 :

<script>
  window.addEventListener('select', function(ev) {
    console.log(ev, ev.timeStamp);
  });
</script>
<input type="text" value="test"><button onclick="document.querySelector('input').select()">select</button>

有谁知道为什么会这样,背后的原理是什么?

我认为发生的事情是触发了两种类型的 select event,但是由于 Event 对象的详细信息集有限,因此它们看起来完全一样。但是看起来当您更改输入的 selectionRange 时会触发一个 select 事件,当实际文本 selection 更改时会触发一个 select 事件(在这种情况下因为 selection 变化导致焦点在输入时被激活)。最后一个是当输入为空时不被触发的那个 - 因为没有文本,所以文本没有变化 selection.

您可以通过将 select() 放在 mousedown 上来分解它。由于它发生在按钮上的 mousedown 上,因此焦点不在输入上,而是停留在按钮上。但是仍然会触发一个事件。然后,如果您只是在 mouseup 上添加 focus(),例如,您不会更改输入的 selectionRange,但实际文本会得到 selected 并触发 select 事件。 或者,如果在您的点击处理程序中调用 select() ,然后在按钮上调用 focus() ,您也将只有一个事件。 你可以在这里看到这些行为:

https://jsfiddle.net/k292po9a/6/

话虽如此,它确实看起来像一个错误,它应该由 Chrome 处理,以便只触发一个事件。