使用".click()"触发事件监听器是同步的吗?

15
我有以下代码(在我的HTML中有一个<button id="7">):
(function() {
  'use strict';
  document.getElementById(7).addEventListener("click", function(){
    console.log('clicked');
  })
  console.log('before');
  document.getElementById(7).click();
  console.log('after')
}());

当这段代码在Firefox 41控制台中运行时,我本来期望会得到以下结果:
before after clicked
因为代码会同步运行,然后在完成脚本后响应点击事件。但实际上我得到的结果是:
before clicked after 这似乎表明事件是同步处理的?

@JavierConde 如果“异步”是指“将事件放置在事件队列中”,那么该事件只能在当前函数堆栈清除后才能解决。我猜它可能会执行一些满足计算机科学定义的“异步”操作,而不是“将事件放置在事件队列中”,但我不熟悉任何JavaScript规范或实现定义这种行为的情况。(也就是说,我所知道的所有异步JS实现都使用一个事件队列,只有在JS引擎空闲时才会弹出。)你能指出哪里可能定义或实现了这样的行为吗? - apsillers
@apsillers,你是对的,我知道JS是单线程的,但我认为它可能有某种机制来触发中断。事实并非如此。 - Javier Conde
1个回答

19

是的,click 方法会同步运行激活步骤,其中包括立即触发(创建和分派)事件。它不会被放入事件循环队列中。


这似乎不仅限于使用click方法。例如,我使用target.dispatchEvent(new Event("hover")来获取悬停事件和mousedown事件的相同结果。我不确定如何概括我的问题,但我通常认为事件会进入事件队列,但这些用户交互事件似乎没有? - Dan
1
是的,dispatchEvent 也是同步的(事实上,它甚至根据侦听器的效果具有返回值)。 - Bergi
你是在暗示如果这些事件是由用户浏览器交互引起的,它们会被异步处理吗? - Dan
对于用户交互来说,"异步"到底是什么意思呢?事件队列只能确保事件按序发生(而不会以某种方式并行进行)。没有任何可能出现"不同步"的情况,比如ajax请求。 - Bergi
我想我的意思是,如果用户交互事件在调用上面的.click()的同时发生,那么它不会中断当前的执行。看起来答案确实是:不会。非常感谢您的帮助。 - Dan

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