【问题标题】:Javascript .replace command replace page text?Javascript .replace 命令替换页面文本?
【发布时间】:2011-11-08 16:37:03
【问题描述】:

JavaScript 命令 .replace 可以替换任何网页中的文本吗?我想创建一个 Chrome 扩展程序来替换任何网页中的特定单词来表达其他内容(例如蛋糕而不是派)。

【问题讨论】:

  • 它只能替换 string 中的值,返回一个 new string。但是,您可以将页面的某些部分抓取到一个字符串中,然后将它们吐回。最简单,但也许最危险的是正文的整个“内部 HTML”。
  • 是的,您似乎必须定位一个所有页面共有的元素,例如<body>

标签: javascript


【解决方案1】:

你尝试过类似的方法吗?

$('body').html($('body').html().replace('pie','cake'));

【讨论】:

    【解决方案2】:

    .replace 方法是一个字符串操作,因此在 HTML 文档上运行该操作并不容易,HTML 文档由 DOM Node 对象组成。

    使用 TreeWalker API

    遍历 DOM 中的每个节点并替换其中的文本的最佳方法是使用 document.createTreeWalker 方法创建一个 TreeWalker 对象。这是许多 Chrome 扩展程序中使用的一种做法!

    // create a TreeWalker of all text nodes
    var allTextNodes = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT),
        // some temp references for performance
        tmptxt,
        tmpnode,
        // compile the RE and cache the replace string, for performance
        cakeRE = /cake/g,
        replaceValue = "pie";
    
    // iterate through all text nodes
    while (allTextNodes.nextNode()) {
        tmpnode = allTextNodes.currentNode;
        tmptxt = tmpnode.nodeValue;
        tmpnode.nodeValue = tmptxt.replace(cakeRE, replaceValue);
    }
    

    要用另一个元素替换部分文本或在文本中间添加一个元素,请使用 DOM splitTextcreateElementinsertBefore 方法,example

    不要使用 innerHTML 或 innerText 或 jQuery .html()

    // the innerHTML property of any DOM node is a string
    document.body.innerHTML = document.body.innerHTML.replace(/cake/g,'pie')
    
    • 通常速度较慢(尤其是在移动设备上)。
    • 它有效地删除和替换了整个 DOM,这不是很棒并且可能有一些副作用:它会破坏 JavaScript 代码中附加的所有事件侦听器(通过 addEventListener 或 .onxxxx 属性),从而破坏部分/全部功能。
    • 但是,这是一种常见、快速且非常肮脏的方法。

    【讨论】:

    • 感谢这些信息,我的解决方案确实很脏
    • +1 表示createTreeWalker。我不知道该功能存在。这很酷。
    • @zetlen 请如何替换cakeRE = 'keyword' by replaceValue = '<a herf=\"#\">keyword</a>';,因为它只显示html代码而不执行它?
    • @Valky 那是因为您正在更改文本节点的字符串值,并且根据定义,文本节点不包含 HTML。您可以使用节点的parentNode 属性在其自身与其父节点之间插入一个锚标记。请将此作为一个单独的问题提出!
    • @zetlen 非常感谢,我创建了一个新问题 stackoverflow.com/questions/13458291/…,因为我发现您使用 createTreeWalker() 的解决方案无法与 Internet Explorer 一起使用...
    【解决方案3】:

    好的,所以 createTreeWalker 方法是正确的方法,它是一个好方法。不幸的是,我需要这样做来支持不支持 document.createTreeWalker 的 IE8。伤心的伊恩很伤心。

    如果您想像顽皮的孩子一样使用非标准的 innerHTML 调用在页面文本上使用 .replace 来执行此操作,您需要小心,因为它会替换标签内的文本,导致 XSS 漏洞和一般破坏您的页面。

    您需要做的只是替换标签之外的文本,我与之匹配:

    var search_re = new RegExp("(?:>[^<]*)(" + stringToReplace + ")(?:[^>]*<)", "gi");
    

    恶心,不是吗。您可能希望通过替换一些结果然后将其余结果保留在 setTimeout 调用中来缓解任何缓慢,如下所示:

    // replace some chunk of stuff, the first section of your page works nicely
    // if you happen to have that organization
    //
    setTimeout(function() { /* replace the rest */ }, 10);
    

    它会在替换第一个块后立即返回,让您的页面继续其快乐的生活。对于您的替换调用,您还需要替换临时字符串中的大块

    var tmp = element.innerHTML.replace(search_re, whatever); 
    /* more replace calls, maybe this is in a for loop, i don't know what you're doing */  
    element.innerHTML = tmp;
    

    以尽量减少重排(当页面重新计算定位并重新渲染所有内容时)。对于大页面,除非您小心,否则这可能会很慢,因此需要优化指针。再一次,除非你绝对需要,否则不要这样做。使用 zetlen 在上面发布的 createTreeWalker 方法..

    【讨论】:

      猜你喜欢
      • 2014-09-12
      • 2017-03-06
      • 1970-01-01
      • 1970-01-01
      • 2011-06-26
      • 2017-08-23
      • 1970-01-01
      • 2013-11-30
      • 2011-05-11
      相关资源
      最近更新 更多