DOM事件优先级

70

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)。


不要忘记这些关键事件:ondragstartondragoverondragendondblclickoncontextmenu - cronoklee
4个回答

40
这在过去并没有明确定义。不同的浏览器可以自由地实现事件顺序。虽然大多数情况下都足够接近,但仍然存在一些奇怪的边缘情况,其中浏览器有所不同(当然,还有更多情况是某些浏览器根本不发送某些事件)。
话虽如此,HTML 5草案推荐确实试图指定事件将如何排队和分派- 事件循环
为了协调事件、用户交互、脚本、渲染、网络等,用户代理必须使用本节所述的事件循环。
每个用户代理必须至少有一个事件循环,并且最多只能有一个与相关的同源浏览上下文单元对应的事件循环。
事件循环具有一个或多个任务队列。任务队列是任务的有序列表[...] 当用户代理要排队任务时,它必须将给定任务添加到相关事件循环的任务队列之一。来自特定任务源的所有任务必须始终添加到同一任务队列中,但来自不同任务源的任务可以放置在不同任务队列中。[...]
[...] 用户代理可以为鼠标和键盘事件(用户交互任务源)设置一个任务队列,为其他所有事件设置另一个任务队列。然后,用户代理可以在三分之三的时间内优先处理键盘和鼠标事件,使界面响应但不会饥饿其他任务队列,并且从任何一个任务源处理事件时不会出现乱序。[...]
请注意最后一段:由浏览器实现决定将哪些事件分组并按顺序处理,以及给任何特定类型的事件分配的优先级。因此,现在或将来没有理由期望所有浏览器都以固定顺序分派所有事件。

30

想了解事件的相对顺序,可以看下面内容。目前我只在Chrome中测试过。

  1. mouseover(鼠标移入)
  2. mousemove(鼠标移动)
  3. mouseout(鼠标移出)

  1. mousedown(鼠标按下)
  2. change(输入框被聚焦时)
  3. blur(元素失去焦点时)
  4. focus(元素获得焦点时)
  5. mouseup(鼠标松开)
  6. click(鼠标点击)
  7. dblclick(鼠标双击)

  1. keydown(键盘按下)
  2. keypress(键盘按键按下)
  3. keyup(键盘按键抬起)

2
如果我触发click事件,是否也会触发之前的事件(mousedown、change、blur、focus、mouseup)? - Oki Erie Rinaldi
dragstart 在这里的哪个位置? - cronoklee

5
如果您正在查看鼠标/触摸事件,Patrick H. Lauke已经发布了有关此主题的讲座。绝对是一篇有趣的阅读材料 - 并处理不同浏览器,不同设备和不同标准的所有怪癖。
他还打包了一个全面的测试集

5

这是一个关于多个事件演示的示例:

<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)')"
   ontouchstart="console.log('ontouchstart')"
    ontouchmove="console.log('ontouchmove')"
     ontouchend="console.log('ontouchend')"
  ontouchcancel="console.log('ontouchcancel')"
    placeholder="edit me"
/>

我注意到在Chrome/Firefox桌面版中,onselectionchangeonkey之前触发,而在安卓版的Chrome上则相反。 https://jsfiddle.net/yv8zg5d1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接