JavaScript命令.replace可以替换任何网页中的文本吗?我想创建一个Chrome扩展程序,用来替换任何网页中的特定单词,以便说出其他内容(例如蛋糕代替馅饼)。
答案 0 :(得分:9)
.replace
方法是一个字符串操作,因此对由DOM Node对象组成的HTML文档运行操作并不是很简单。
通过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);
}
// the innerHTML property of any DOM node is a string
document.body.innerHTML = document.body.innerHTML.replace(/cake/g,'pie')
答案 1 :(得分:1)
好的,所以createTreeWalker方法是这样做的正确方法,这是一个好方法。不幸的是,我需要这样做才能支持不支持document.createTreeWalker的IE8。悲伤的伊恩很难过。
如果你想使用非标准的innerHTML调用(如顽皮的孩子)在页面文本上使用.replace,你需要小心,因为它会替换标签内的文本,导致XSS漏洞和一般破坏你的页面。
您需要做的只是替换我匹配的标签OUTSIDE:
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方法..
答案 2 :(得分:0)
$('body').html($('body').html().replace('pie','cake'));