javascript - 当我通过 chrome 扩展的内容脚本修改网页中的单词时,超出了最大调用堆栈大小

标签 javascript html css dom

我正在构建一个查找单词的 Chrome 扩展程序,如果该单词出现在网页上,它就会变得模糊。为此,我在网页上查找所有文本(节点类型 1)节点,并将它们替换为新节点。当我创建一个新节点并将要替换的节点的文本分配给它时出现问题,运行时此脚本给出错误“RangeError:超出最大调用堆栈大小”

当我将常量字符串分配给要创建的节点时,不会出现此问题。这个脚本运行良好。

var targetNode=document.body    
var config = { attributes: true, childList: true, subtree: true };
var callback = function(mutationsList, observer) {
walk(document.body);
};


var observer = new MutationObserver(callback);
observer.observe(targetNode, config);

function walk(node) 
{
var child, next;

switch ( node.nodeType )  
{
    case 1:  // Element
    case 9:  // Document
    case 11: // Document fragment
        child = node.firstChild;
        while ( child ) 
        {
            next = child.nextSibling;
            walk(child);
            child = next;
        }
        break;

    case 3: // Text node
        handleText(node);
        break;
}
}

function handleText(textNode) 
{

var str = textNode.nodeValue;
if (str == "Manchester"){
//console.log(str);

p=textNode.parentNode;
const modified = document.createElement('span');
modified.id="bblur";
modified.textContent = "Constant";     // this works
modified.style.filter="blur(5px)";
modified.addEventListener("mouseover", mouseOver, false);
modified.addEventListener("mouseout", mouseOut, false);
p.replaceChild(modified, textNode);
}

//textNode.nodeValue = str;

//textNode.style.filter="blur(5px)";

}


function mouseOver()
{  
this.style.filter="blur(0px)";
}

function mouseOut()
{  
this.style.filter="blur(5px)";
}

这个 handleText 函数不起作用

function handleText(textNode) 
{

var str = textNode.nodeValue;
if (str == "Manchester"){
//console.log(str);

p=textNode.parentNode;
const modified = document.createElement('span');
modified.id="bblur";
modified.textContent = str;   //this doesn't work :/
modified.style.filter="blur(5px)";
    modified.addEventListener("mouseover", mouseOver, false);
    modified.addEventListener("mouseout", mouseOut, false);
p.replaceChild(modified, textNode);
}


}

我不希望使用固定字符串创建新节点,但我希望新节点中包含旧节点的文本内容。我可以做些什么来避免这个调用堆栈限制达到问题。谢谢!

最佳答案

死循环是因为你在 MutationObserver 回调中修改了 DOM。它与 "Constant" 一起工作,因为您有条件 "if (str == "Manchester")" 可以防止 DOM 修改并且不会触发 MutationObserver 回调。尝试使用常量 "Manchester",您将再次看到无限循环。 最简单的解决方法是忽略您已经替换的节点:

function walk(node) 
{
  var child, next;

  switch ( node.nodeType )  
  {
      case 1:  // Element
      case 9:  // Document
      case 11: // Document fragment
          child = node.firstChild;
          while ( child ) 
          {
              next = child.nextSibling;
              if (child.id !== 'bblur') {
                  walk(child);
              }
              child = next;
          }
          break;

      case 3: // Text node
          handleText(node);
          break;
  }
}

您的代码还将为所有替换元素分配相同的 ID。最好使用不同的方式来标记新节点,例如您可以使用 dataset 属性。

关于javascript - 当我通过 chrome 扩展的内容脚本修改网页中的单词时,超出了最大调用堆栈大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56555733/

相关文章:

jquery - 如何从 jQuery UI Selectable 中排除 anchor 标记?

javascript - CSS:如何判断某个ttf字体具有的特征?

javascript - Next Js 结合外部 REST API 身份验证和授权

javascript - 单击按钮清除填充的下拉列表

javascript - 使用 Knockout 和 jQuery 延迟加载图像

javascript - 如何根据随机尺寸绘制正方形并显示大小

javascript - 获取 *ngFor 中的文本长度

javascript - 关于重定向通知 - PHP/JS

jquery - 无法使用 xpath 定位人体部位图像的元素

javascript - slider 上的按钮没有响应