【问题标题】:Why the event did not cause an endless loop?为什么事件没有造成死循环?
【发布时间】:2018-04-25 16:50:27
【问题描述】:

var domInner = document.querySelector('#inner')
var domWrapper = document.querySelector('#wrapper')
domInner.onclick = innerHandler
function innerHandler () {
  console.log('inner')
}
domWrapper.onclick = wrapperHandler
function wrapperHandler () {
  // setTimeout(() => {
    console.log('wrapper')
    domInner.click()
  // }, 1000)
}
domInner.click()
<div id="wrapper">
  wrapper
  <div id="inner">
    inner
  </div>
</div>

我们可以看到,函数wrapperHandler中的domInner.click()并没有触发domInner的点击事件。

我以前以为会,domInner的点击事件会传播到domWrapper,所以这可能会导致死循环。

但它没有。那么,究竟是什么原因呢?

在我打开setTimeout之后,它就会发生。

为什么函数wrapperHandler中的domInner.click()没有再次触发domInner的点击事件?为什么该事件没有导致死循环?

谢谢。

【问题讨论】:

    标签: javascript dom-events event-bubbling event-propagation


    【解决方案1】:

    如果您手动单击内部元素,您会注意到它会导致日志触发两次。一次用于实际的点击元素,然后再次用于您使用element.click() 触发的“模拟”元素。

    为什么它不继续循环?好吧,看起来每次event loop 迭代每个元素只能发出一次“模拟”点击。在同一迭代中从同一元素再次发出它的尝试将被忽略。当您将setTimeout 放入其中时它允许它的原因是因为setTimeout 将它放在稍后的事件循环迭代中。

    这似乎是element.click 方法的内置功能,可能是为了防止这种无限循环。不幸的是,documentation on MDN 不是特别详细,我不确定还有什么地方可以确认。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-13
      • 2016-04-21
      • 1970-01-01
      相关资源
      最近更新 更多