javascript - 用户触发的 'click'事件回调的执行与编程触发的有什么区别?

标签 javascript google-chrome events

我正在阅读 Jake Archibald 关于任务、微任务等的文章。在他的示例中,我们看到“控制台日志”以特定顺序打印基于用户的点击事件,而以不同的顺序打印以编程方式触发的点击事件。我请求是否有人可以更详细地解释一下这两种情况下的点击回调执行情况。

HTML

<div class="outer-test"><div class="inner-test"></div></div>

CSS

.outer-test {
  background: #D4D4D4;
  padding: 25px;
  width: 92px;
  margin: 0 auto;
}

.inner-test {
  background: #ADADAD;
  padding: 46px;
  width: 0;
}

JS(第一种情况)

var outer = document.querySelector('.outer-test');
var inner = document.querySelector('.inner-test');


new MutationObserver(function() {
  console.log('mutate');
}).observe(outer, {
  attributes: true
});


function onClick() {
  console.log('click');

  setTimeout(function() {
    console.log('timeout');
  },0);

  Promise.resolve().then(function() {
    console.log('promise');
  });

  outer.setAttribute('data-random', Math.random());
}


inner.addEventListener('click', onClick);
outer.addEventListener('click', onClick);


JS(第二种情况)

var outer = document.querySelector('.outer-test');
var inner = document.querySelector('.inner-test');


new MutationObserver(function() {
  console.log('mutate');
}).observe(outer, {
  attributes: true
});


function onClick() {
  console.log('click');

  setTimeout(function() {
    console.log('timeout');
  },0);

  Promise.resolve().then(function() {
    console.log('promise');
  });

  outer.setAttribute('data-random', Math.random());
}


inner.addEventListener('click', onClick);
outer.addEventListener('click', onClick);

inner.click();  //<======== 

引用:https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/

最佳答案

.click() causes the event to dispatch synchronously, so the script that calls .click() is still in the stack between callbacks.

他浏览了答案,但基本上就是这样。我不会假装我完全理解细节,但当我读到它时:因为点击是在与设置事件监听器的代码相同的“框架”中的 JavaScript 中触发的,并且以这种方式触发事件是同步的回调之后直接运行,因为它不允许检查微任务队列的突变。

在第一种情况下,“设置”完成并且“框架”结束。因此,只有在浏览器中单击才会触发事件,然后这将在另一个框架中(异步)发生,并且由于此时没有其他“框架”正在运行,因此它会首先检查微任务队列中的突变。

The above rule ensures microtasks don't interrupt JavaScript that's mid-execution.

这似乎就是为什么没有这样做的原因,这是有道理的,因为它都是单线程的(你知道,有点),让“框架”完成是有意义的。

因此,奇怪之处在于以编程方式触发事件会强制所有事件进入同步状态。

关于javascript - 用户触发的 'click'事件回调的执行与编程触发的有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58292052/

相关文章:

events - 将事件处理代码放入自己的方法中是不是一个好的设计?

javascript - 在jQuery插件内部使用YouTube Iframe API获取状态

javascript - ES6 类中带有 super 的模板文字

css - Google Chrome 自动表单填充突出显示

javascript - setInterval Chrome 与 Firefox

windows - 如何导出带有详细消息的 Windows 事件日志

javascript - jQuery:如何为输入字段值设置固定小数

javascript - Joomla javascript css 类不更新

python - Anaconda Selenium 和 Chrome

javascript - 如何在修改 DOM 后使自定义文本编辑器使用撤消和重做快捷方式?