【问题标题】:Replace text but keep links in google chrome extension content scripts替换文本但在 google chrome 扩展内容脚本中保留链接
【发布时间】:2016-04-17 06:27:09
【问题描述】:

我正在尝试替换 google chrome 上的单词,但遇到了问题。我能够成功替换特定的单词,但它会杀死相关的 html 链接。

我怎样才能使链接保持活动状态并仍然替换文本?

这是我的 chrome 扩展内容脚本中的代码:

wordDict = {"the":"piano","and":"Hello", "a":"huh?"};

for (word in wordDict) {
    document.body.innerHTML = document.body.innerHTML.replace(
        new RegExp('\\b' + word + '\\b',"gi"), wordDict[word]
    );
};

【问题讨论】:

  • 用innerText代替innerHTML怎么样?
  • 通过简单地遍历 DOM 树。与其进行脑死的简单正则表达式替换,不如查看树中每个节点的 .innerTextmember 并替换 there 中的文本。 (a) 它不会触及链接目标,(b) 它不会导致任何事件侦听器被丢弃。
  • 如果你可以使用 jQuery..$('a').text("Anything"); 你也可以运行 jQuery.each() 迭代器
  • innerText 似乎破坏了整个网站,只是吐出一堆未格式化的文本——这不是我想要的。
  • 我确实加载了 jquery。给我一点时间来了解您的 jquery 代码的含义,以便我可以针对我的问题对其进行格式化。

标签: javascript text replace google-chrome-extension content-script


【解决方案1】:

我不是正则表达式方面的专家,因此这是一种解决方案,可以在包含一个单词的页面上找到一个超链接并将其替换为另一个。

for(var i = 0, l=document.links.length; i<l; i++) {
  if(document.links[i].innerText == "Word"){
    document.links[i].innerText = "Other Word";
  }
}

这样你可以避免正则表达式,但你仍然需要循环你的 words 对象。

另一方面,既然你说你已经加载了 jQuery,这个 jQuery 解决方案会按照你的意图去做,它会在所有标签中查找单词并替换它们。

jQuery.each( wordDict , function( key, value ) {
  jQuery( "a" ).each(function(){
    if(jQuery(this).text().match(key)) jQuery(this).text(value);
  });
});

第一个 jQuery 每个循环字符串对象,第二个每个循环遍历页面上的所有标签,如果匹配,它会根据对象上的值更改元素文本。

【讨论】:

  • 不要说出你的答案,就好像你只是在粘贴随机代码 sn-p 并且不确定它是否有效。即使它有效并且对其他人没有帮助,它也不会使它看起来很好。解释问题并给出你认为可行的答案(并解释原因)——如果不行,就会有人在 cmets 中告诉你。
  • 我都测试了,并不意味着它对他有用。如你所见,我正在尽我所能理解和帮助他,也许这些话不是最好的(“这有效吗?适合你吗?”)但我只是想获得他对我的方法的反馈
  • 我认为提问没有问题,但这实际上是您的回答中唯一附带的文字。如果您可以将其重组为“(简短解释)(代码)有帮助吗?”这将是一个更好的答案。
【解决方案2】:

好的! 2 周后,我终于解决了这个问题。被忽略的是 DOM 中的子节点。我在下面使用的代码有效地解决了子节点并保持了脚本的原始外观!

function replaceText(jsonArr) {
$("body *").textFinder(function() {
    for (var key in jsonArr) {
        var matcher = new RegExp('\\b' + key + '\\b', "gi");
        this.data = this.data.replace(matcher, jsonArr[key]);
    }
});
}

// jQuery plugin to find and replace text
jQuery.fn.textFinder = function( fn ) {
this.contents().each( scan );
// callback function to scan through the child nodes recursively
function scan() {
    var node = this.nodeName.toLowerCase();
    if( node === '#text' ) {
        fn.call( this );
    } else if( this.nodeType === 1 && this.childNodes && this.childNodes[0] && node !== 'script' && node !== 'textarea' ) {
        $(this).contents().each( scan );
    }
}
return this;
};

【讨论】:

    猜你喜欢
    • 2011-08-13
    • 2019-11-05
    • 1970-01-01
    • 1970-01-01
    • 2022-11-07
    • 2013-01-02
    • 1970-01-01
    • 1970-01-01
    • 2013-09-01
    相关资源
    最近更新 更多