Input 点击触发的事件顺序

点击 input 元素依次触发的事件及其顺序

问题

点击一个 input 元素,会依次触发哪些事件?

解答

点击 input 元素会按以下顺序触发事件:

  1. mousedown - 鼠标按下
  2. focus - 获得焦点(如果之前没有焦点)
  3. mouseup - 鼠标释放
  4. click - 点击完成

验证代码

<!DOCTYPE html>
<html>
<head>
  <title>Input 事件顺序</title>
</head>
<body>
  <input type="text" id="myInput" placeholder="点击我">
  <div id="log"></div>

  <script>
    const input = document.getElementById('myInput');
    const log = document.getElementById('log');

    // 记录事件触发顺序
    const events = ['mousedown', 'focus', 'mouseup', 'click'];

    events.forEach(eventName => {
      input.addEventListener(eventName, () => {
        log.innerHTML += `${eventName}<br>`;
        console.log(eventName);
      });
    });
  </script>
</body>
</html>

完整的鼠标事件顺序

如果考虑更多事件,完整顺序是:

const input = document.getElementById('myInput');

const allEvents = [
  'mouseenter',  // 鼠标进入(不冒泡)
  'mouseover',   // 鼠标进入(冒泡)
  'mousemove',   // 鼠标移动
  'mousedown',   // 鼠标按下
  'focus',       // 获得焦点
  'mouseup',     // 鼠标释放
  'click',       // 点击
];

allEvents.forEach(event => {
  input.addEventListener(event, () => console.log(event));
});

// 点击 input 输出:
// mouseenter
// mouseover
// mousemove (可能多次)
// mousedown
// focus
// mouseup
// click

双击事件顺序

// 双击时的事件顺序
// mousedown -> focus -> mouseup -> click
// mousedown -> mouseup -> click -> dblclick

关键点

  • focus 事件在 mousedown 之后、mouseup 之前触发
  • click 事件在 mouseup 之后触发,是鼠标按下并释放的完整动作
  • 如果 input 已有焦点,再次点击不会触发 focus 事件
  • mousedown 中调用 preventDefault() 可以阻止 input 获得焦点
  • 双击时会触发两次 click,最后触发一次 dblclick