Javascript Chrome扩展,用于在显示文本之前替换网页和Facebook帖子中的文本
我正在开发一个Chrome扩展,它可以替换网页文本中指定的字符串或正则表达式 总体而言,它运行良好,但我想解决两个问题: (1) 在进行文本替换之前,将显示原始的、未更改的网页文本 (2) 文本替换不会影响在滚动到页面底部后动态加载的Facebook帖子 下面是代码,从中改编,稍作修改Javascript Chrome扩展,用于在显示文本之前替换网页和Facebook帖子中的文本,javascript,regex,google-chrome-extension,replace,Javascript,Regex,Google Chrome Extension,Replace,我正在开发一个Chrome扩展,它可以替换网页文本中指定的字符串或正则表达式 总体而言,它运行良好,但我想解决两个问题: (1) 在进行文本替换之前,将显示原始的、未更改的网页文本 (2) 文本替换不会影响在滚动到页面底部后动态加载的Facebook帖子 下面是代码,从中改编,稍作修改 // manifest.json { "manifest_version": 2, "name": "Replace Text", "version": "1.0", "co
// manifest.json
{
"manifest_version": 2,
"name": "Replace Text",
"version": "1.0",
"content_scripts": [ {
"js": [ "jquery.min.js", "replace.js" ],
"matches": [ "<all_urls>" ],
"run_at": "document_end"
} ]
}
// replace.js
jQuery.fn.textWalk = function( fn ) {
this.contents().each( jwalk );
function jwalk() {
var nn = this.nodeName.toLowerCase();
if( nn === '#text') {
fn.call( this );
} else if( this.nodeType === 1 && this.childNodes && this.childNodes[0] && nn !== 'script' && nn !== 'textarea' ) {
$(this).contents().each( jwalk );
}
}
return this;
};
$('body').textWalk(function() {
this.data = this.data.replace('This Text', 'That Text');
this.data = this.data.replace(/[Rr]eplace\s[Ss]ome\s[Tt]ext/g, 'with other text');
});
//manifest.json
{
“清单版本”:2,
“名称”:“替换文本”,
“版本”:“1.0”,
“内容脚本”:[{
“js”:[“jquery.min.js”,“replace.js”],
“匹配项”:[“”],
“运行时间”:“文档结束”
} ]
}
//替换.js
jQuery.fn.textwark=函数(fn){
this.contents().each(jwalk);
函数jwalk(){
var nn=this.nodeName.toLowerCase();
如果(nn=='#text'){
fn.呼叫(本);
}else if(this.nodeType==1&&this.childNodes&&this.childNodes[0]&&nn!='script'&&nn!='textarea'){
$(this).contents().each(jwalk);
}
}
归还这个;
};
$('body').textWalk(函数(){
this.data=this.data.replace('this Text','That Text');
this.data=this.data.replace(/[Rr]eplace\s[Ss]ome\s[Tt]ext/g,'用其他文本');
});
我在网上找到了一些部分答案,但无法让它们正常工作
例如,一个建议的解决方案是将
的“运行时间”:“文档结束时间”
更改为的“运行时间”:“文档开始时间”
。这会在构建DOM之前运行内容脚本,因此理论上它应该在显示任何内容之前进行文本替换。但在我的例子中,它导致扩展完全停止替换文本。一个可行的替代方法是通过监听DOM更改,并动态更改TextNodes(或任何内容)的内容。从技术上讲,这在渲染任何内容之前都不会发生,但它应该足够近,用户不会注意到(除非您所做的更改非常大)
另请参见我对a的回答
示例代码
(这仍然需要微调,例如处理动态节点更新。)
content.js:
// Modify the content somehow...
var doFilter = function(textNode) {
textNode.data = textNode.data + "<br />" + textNode.data;
}
// Create a MutationObserver to handle events
// (e.g. filtering TextNode elements)
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.addedNodes) {
[].slice.call(mutation.addedNodes).forEach(function(node) {
if (node.nodeName.toLowerCase() == "#text") {
doFilter(node);
}
});
}
});
});
// Start observing "childList" events in document and its descendants
observer.observe(document, {
childList: true,
subtree: true
});
...
"content_scripts": [
{
"matches": [...],
"js": ["content.js"],
"run_at": "document_start",
"all_frames": true
}
],
...
如果您决定采用方法,那么有一个JS库可以让您的生活更轻松:
关于您的问题,为什么在“文档开始”执行脚本没有任何效果:
发生这种情况是因为当时(“document_start”)没有可替换的脚本(即,在将任何其他内容添加到DOM之前加载并运行该脚本)。您尝试过我的建议吗?它对你有用吗?它在大多数网站上都有用,但我无法在Facebook上使用它(甚至连页面第一次加载时出现的第一篇帖子都不行)。作为替代方案,我可以使用事件侦听器在出现新的AJAX请求时重新运行replace函数。。。认为这值得一试吗?正如我在回答中指出的,提供的示例代码仍然需要修改,例如,处理动态节点更新。我会坚持使用MutationObserver,试图找出FB页面上“幕后”实际发生了什么,然后决定如何对DOM更改进行修改(和响应)。(对不起,我不能再帮你了,因为我不在FB上。)好的,我会再做一些,看看会发生什么——非常感谢你的帮助!