DOM 事件优先级

IT技术 javascript event-handling dom-events eventqueue
2021-02-08 17:04:17

在 JavaScript 中处理事件的优先顺序是什么?

以下是按字母顺序排列的事件...

  1. onabort - 图像加载中断
  2. onblur - 元素失去焦点
  3. onchange - 用户更改字段的内容
  4. onclick - 鼠标点击一个对象
  5. ondblclick - 鼠标双击一个对象
  6. onerror - 加载文档或图像时发生错误
  7. onfocus - 一个元素获得焦点
  8. onkeydown - 按下键盘键
  9. onkeypress - 按下或按住键盘键
  10. onkeyup - 释放键盘键
  11. onload - 页面或图像已完成加载
  12. onmousedown - 按下鼠标按钮
  13. onmousemove - 鼠标移动
  14. onmouseout - 鼠标从元素上移开
  15. onmouseover - 鼠标移动到一个元素上
  16. onmouseup - 释放鼠标按钮
  17. onreset - 单击重置按钮
  18. onresize - 调整窗口或框架的大小
  19. onselect - 文本被选中
  20. onsubmit - 点击提交按钮
  21. onunload - 用户退出页面

它们在事件队列之外处理的顺序是什么?

我相信优先级不是先进先出(FIFO)。

4个回答

据我所知,这在过去没有明确定义。不同的浏览器可以随意实现事件排序,但它们认为合适。虽然大多数对于所有实际目的都足够接近,但已经并且继续存在一些奇怪的边缘情况,其中浏览器有所不同(当然,还有更多的情况是某些浏览器根本无法发送某些事件)。

也就是说,HTML 5 草案建议确实尝试指定事件将如何排队和分派 -事件循环

为了协调事件、用户交互、脚本、渲染、网络等,用户代理必须使用本节中描述的事件循环。

每个用户代理必须至少有一个事件循环,并且每个相关的同源浏览上下文单元最多有一个事件循环。

一个事件循环有一个或多个任务队列。任务队列是任务的有序列表[...] 当用户代理要对任务进行排队时,它必须将给定的任务添加到相关事件循环的任务队列之一。来自一个特定任务源的所有任务必须始终添加到同一个任务队列中,但是来自不同任务源的任务可以放置在不同的任务队列中。[...]

[...] 用户代理可以有一个用于鼠标和键事件(用户交互任务源)的任务队列,另一个用于其他所有事件。然后,用户代理可以在四分之三的时间内将键盘和鼠标事件优先于其他任务,保持界面响应但不会使其他任务队列挨饿,并且永远不会处理来自任何一个任务源的事件无序。[...]

请注意最后一点:由浏览器实现决定哪些事件将被组合在一起并按顺序处理,以及任何特定类型事件的优先级。因此,没有理由期望所有浏览器现在或将来以固定顺序分派所有事件。

对于任何想知道序列相关事件被调用的人,请参见下文。到目前为止,我只在 Chrome 中进行了测试。

  1. 鼠标移到
  2. 鼠标移动
  3. 鼠标移出

  1. 鼠标按下
  2. 改变(聚焦输入)
  3. 模糊(在聚焦元素上)
  4. 重点
  5. 鼠标向上
  6. 点击
  7. 双击

  1. 按键
  2. 按键
  3. 按键
哪里dragstart适合这里?
2021-03-18 17:04:17
如果我触发click事件,我是否也触发了之前的事件(mousedown、change、blur、focus、mouseup)?
2021-04-05 17:04:17

如果您正在研究鼠标/触摸事件,Patrick H. Lauke 发表了一篇关于该主题的演讲绝对是一本有趣的读物——并且处理了不同浏览器、不同设备和不同标准的所有怪癖。

他还捆绑了一套全面的测试

这是一些事件的演示:

<input  onclick="console.log('onclick - Mouse clicks an object')" 
     ondblclick="console.log('ondblclick - Mouse double-clicks an object')"
    onmousedown="console.log('onmousedown - A mouse button is pressed')"
      onmouseup="console.log('onmouseup - A mouse button is released')"
    onmousemove="console.log('onmousemove - The mouse is moved')"
   onmouseenter="console.log('onmousenter - The mouse is moved over an element (not bubbling)')"
    onmouseover="console.log('onmouseover - The mouse is moved over an element')"
     onmouseout="console.log('onmouseout - The mouse is moved off an element')"
   onmouseleave="console.log('onmouseout - The mouse is moved off an element (not bubbling)')"
       onchange="console.log('onchange - The user changes the content of a field')"
      onfocusin="console.log('onfocusin - An element gets focus')"
        onfocus="console.log('onfocus - An element gets focus (not bubbling)')"
      onkeydown="console.log('onkeydown - A keyboard key is pressed')"
     onkeypress="console.log('onkeypress - A keyboard key is pressed or held down')"
onselectionchange="console.log('onselectionchange - The caret position changed')"
        onkeyup="console.log('onkeyup - A keyboard key is released')"
       onselect="console.log('onselect - Text is selected')"
     onfocusout="console.log('onfocusout - Loosing focus')"
         onblur="console.log('onblur - Loosing focus (not bubbling)')"
/>

我注意到onselectionchange之前在 chrome/firefox 桌面上触发onkey,而在 android chrome 上则相反。