未捕获的 RangeError:innerHTML 超出了最大调用堆栈大小

Posted

技术标签:

【中文标题】未捕获的 RangeError:innerHTML 超出了最大调用堆栈大小【英文标题】:Uncaught RangeError: Maximum call stack size exceeded with innerHTML 【发布时间】:2013-05-04 05:15:32 【问题描述】:

我对 javascript 不是很有经验,但我遇到了一个我无法理解的问题。我的代码很简单:

document.getElementById ('chat_line_list').addEventListener ("DOMSubtreeModified", LocalMain, false);

function LocalMain ()

    var chatList = document.getElementById('chat_line_list').lastChild.lastElementChild.innerhtml;
    chatList = chatList.replace('InfoThump', '<span class="newemo-1 emoticon"></span>');
    chatList = chatList.replace('MuskMelon', '<span class="newemo-2 emoticon"></span>');
    chatList = chatList.replace('PoisonApple', '<span class="newemo-3 emoticon"></span>');
    chatList = chatList.replace('PoisonBanana', '<span class="newemo-4 emoticon"></span>');
    chatList = chatList.replace('PoisonWatermelon', '<span class="newemo-5 emoticon"></span>');
    chatList = chatList.replace('PoisonGrape', '<span class="newemo-6 emoticon"></span>');
    chatList = chatList.replace('NotNippy', '<span class="newemo-7 emoticon"></span>');
    document.getElementById('chat_line_list').lastChild.lastElementChild.innerHTML = chatList;

异常发生在 LocalMain() 函数的最后一行,当我用新修改的字符串替换 innerHTML 时。这段代码中是否存在导致循环或溢出的内容?

【问题讨论】:

【参考方案1】:

您正在导致无限循环!

您正在收听元素 chat_line_list 上的 DOMSubtreeModified,然后在附加到该事件的函数内更新该元素!

【讨论】:

你说得对,我不敢相信我错过了。我可以通过仅在字符串已被修改时才运行最后一行来发布快速而肮脏的修复,因此该函数将被调用两次。你能想出一个只运行一次的好方法吗? 好的,我通过监听 DOMNodeInserted 而不是 DOMSubtreeModified 解决了我的问题。这在聊天客户端的上下文中是有意义的。感谢您的帮助!【参考方案2】:

试试这个

document.getElementById ('chat_line_list').addEventListener ("DOMSubtreeModified", LocalMain, false);

function LocalMain ()

    var chatList = document.getElementById('chat_line_list').lastChild.lastElementChild.innerHTML;
    chatList = chatList.replace('InfoThump', '<span class="newemo-1 emoticon"></span>');
    chatList = chatList.replace('MuskMelon', '<span class="newemo-2 emoticon"></span>');
    chatList = chatList.replace('PoisonApple', '<span class="newemo-3 emoticon"></span>');
    chatList = chatList.replace('PoisonBanana', '<span class="newemo-4 emoticon"></span>');
    chatList = chatList.replace('PoisonWatermelon', '<span class="newemo-5 emoticon"></span>');
    chatList = chatList.replace('PoisonGrape', '<span class="newemo-6 emoticon"></span>');
    chatList = chatList.replace('NotNippy', '<span class="newemo-7 emoticon"></span>');

    document.getElementById ('chat_line_list').removeEventListener ("DOMSubtreeModified", LocalMain);

    document.getElementById('chat_line_list').lastChild.lastElementChild.innerHTML = chatList;

    document.getElementById ('chat_line_list').addEventListener ("DOMSubtreeModified", LocalMain, false);


【讨论】:

【参考方案3】:

是的,基本上你是说每次修改该元素时,都应该执行LocalMain。由于LocalMain 也改变了元素,它被再次执行,一次又一次,......

您可以尝试删除 EventListener 并在之后再次添加它(没有尝试过,所以我无法告诉您它是否可以工作......)

function LocalMain ()

    var chatList = document.getElementById('chat_line_list').lastChild.lastElementChild.innerHTML;
    chatList.removeEventListener("DOMSubtreeModified", LocalMain, false);
    chatList = chatList.replace('InfoThump', '<span class="newemo-1 emoticon">
    (...)
    chatList = chatList.replace('NotNippy', '<span class="newemo-7 emoticon"></span>');
    document.getElementById('chat_line_list').lastChild.lastElementChild.innerHTML = chatList;
    chatList.addEventListener ("DOMSubtreeModified", LocalMain, false);

【讨论】:

【参考方案4】:

我建议在使用 setTimeout() 方法调用您的函数之前等待 100 微秒。这对我来说很好 - 到目前为止没有错误。

    document.getElementById ('chat_line_list').addEventListener("DOMSubtreeModified", setTimeout(LocalMain, 100), false);

请注意,此解决方案远非完美。 此功能仍在经常执行。

【讨论】:

以上是关于未捕获的 RangeError:innerHTML 超出了最大调用堆栈大小的主要内容,如果未能解决你的问题,请参考以下文章

未捕获的 RangeError:Chrome 上的语言标签无效

未捕获的 RangeError:仅在生产中超出最大调用堆栈大小

“未捕获的 RangeError:在 Dt (jquery.min.js:2) 处超出了最大调用堆栈大小”

未捕获的类型错误:无法读取 null 的属性“innerHTML”

语法中的 innerHTML 错误不起作用;未捕获的 TypeError:无法设置 null 的属性(设置“innerHTML”)[重复]

未捕获的类型错误:无法将属性“innerHTML”设置为 null