You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何该DOM事件触发操作未造成无限循环?

为什么wrapperHandler里的domInner.click()没触发无限循环?

先把你的代码清晰列出来,方便分析:

HTML结构

<div id="wrapper"> wrapper <div id="inner"> inner </div> </div>

JavaScript代码

var domInner = document.querySelector('#inner')
var domWrapper = document.querySelector('#wrapper')
domInner.onclick = innerHandler
function innerHandler () { console.log('inner') }
domWrapper.onclick = wrapperHandler
function wrapperHandler () { 
    console.log('wrapper') 
    domInner.click() 
}
domInner.click()

其实直接跑这段代码,是会触发递归调用的,但不会真的“无限”循环下去——原因和JavaScript的调用栈机制有关:

JavaScript的调用栈有最大深度限制(不同浏览器的数值不一样,比如Chrome大概是一万次上下)。当你在wrapperHandler里调用domInner.click(),会同步触发新一轮的click事件:先执行innerHandler,然后事件冒泡到wrapper再次触发wrapperHandler,这样层层递归,调用栈会越来越深。一旦超过浏览器允许的最大深度,就会抛出RangeError: Maximum call stack size exceeded的错误,直接终止递归,所以你看不到无限循环持续下去。

另外看你代码里注释掉了setTimeout,如果把domInner.click()放到setTimeout里,情况会变:异步调用不会占用当前的调用栈,而是把事件放到下一个事件循环里执行,这时候不会触发栈溢出,但会无限循环下去(控制台会不断输出inner和wrapper),直到你关闭页面或者手动终止脚本。

还有一种小概率情况:如果你的代码写法有误(比如不小心把console.log和domInner.click()都写到注释里了,导致wrapperHandler是空函数),那自然不会有任何递归调用,也就不会出现循环。不过从你的问题描述来看,应该是第一种调用栈限制的情况。

内容的提问来源于stack exchange,提问作者Theer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:36:46