Chrome扩展程序可在文本显示之前替换文字,网页和Facebook文章 [英] Chrome extension to replace text, in web pages and Facebook posts, before text is displayed

查看:261
本文介绍了Chrome扩展程序可在文本显示之前替换文字,网页和Facebook文章的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个Chrome扩展程序,用于替换网页文本中的指定字符串或RegEx。



它的整体效果很好,但有两个问题需要解决:

(2)文字替换不会影响在您滚动到页面后动态加载的Facebook帖子。 底部。



以下代码由 https://

  // manifest.json 

{
manifest_version:2,
name:替换文本,
版本: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);

函数jwalk(){
var nn = this.nodeName.toLowerCase();
if(nn ==='#text'){
fn.call(this);
} else if(this.nodeType === 1&& this.childNodes&&&&&&&&&&&& amp; nn!=='script'&& nn!= ='textarea'){
$(this).contents()。each(jwalk);
}
}
返回此;
};
$ b $('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');
});

我在网上找到了部分答案,但无法让它们正常工作。例如,一个建议的解决方案是将run_at:document_end更改为run_at:document_start。这在DOM构建之前运行内容脚本,因此理论上它应该在显示任何内容之前进行文本替换。但在我的情况下,它导致扩展停止替换文本。

一个可行的替代方法是监听DOM更改指 MutationObserver 和更改TextNodes的内容(或任何曾经)。从技术上讲,之前不会发生任何事情,但它应该足够接近以便用户不会注意到(除非您做出的更改非常庞大)。



另请参阅 类似问题

示例代码



(这仍然需要twicking,例如处理动态)



content.js:

  //以某种方式修改内容... 
var doFilter = function(textNode){
textNode.data = textNode.data +< br /> + textNode.data;
}

//创建一个MutationObserver来处理事件
//(例如过滤TextNode元素)
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);
}
});
}
});
});

//开始观察文档及其后代中的childList事件
observer.observe(document,{
childList:true,
subtree:true
});

(以上代码用于侦听添加的节点,您可能希望让观察者侦听 characterData childList 更改主体及其后代用于捕捉动态加载/更改的内容。)



manifest.json

  ... 
content_scripts:[
{
matches:[...],
js:[content.js],
run_at: document_start,
all_frames:true
}
],
...

如果您决定使用 MutationObserver 方法,这个JS库可以让你的生活更轻松: 突变总结






关于你的问题,为什么在document_start执行你的脚本没有任何作用:

这种情况​​发生,因为那时(document_start)你的脚本没有任何东西可以替换(即,它会在任何其他内容添加到DOM之前加载并运行)。


I'm working on a Chrome extension that replaces specified strings or RegEx's in the text of a web page.

It works well overall, but with two issues that I'd like to solve:

(1) The original, unchanged webpage text is displayed before the text replacement occurs.

(2) The text replacement doesn't affect Facebook posts that are dynamically loaded after you scroll to the bottom of the page.

Here's the code, adapted from https://stackoverflow.com/a/6012345#6012345 with minor changes.

// 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');  
});

I found some partial answers online, but couldn’t get them to work right.

For example, one proposed solution was to change "run_at": "document_end" to "run_at": "document_start". This runs content scripts before the DOM is constructed, so in theory it should do the text replacement before anything is displayed. But in my case it caused the extension to stop replacing text altogether.

解决方案

A viable alternative would be to listen for DOM changes by means of a MutationObserver and change the content of TextNodes (or what ever) on the fly. Technically, this does not happen before anything is being rendered, but it should be close enough for the user not to notice (unless the changes you make are massive).

See, also, my answer to a similar question.

Sample code

(This still needs twicking, e.g. to handle dynamic node updates.)

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
});

(The above code it for listening for added nodes. You might want to have an observer listen for characterData and childList changes in body and its descendants for "catching" dymanically loaded/changed content.)

manifest.json:

...
"content_scripts": [
    {
        "matches": [...],
        "js":         ["content.js"],
        "run_at":     "document_start",
        "all_frames": true
    }
],
...

If you decide to go for the MutationObserver approach, there is this JS library that is supposed to make your life easier: mutation-summary


Regarding your question, why executing your script at "document_start" does not have any effect:
This happens, because at that time ("document_start") there is nothing for your script to replace (i.e. it is loaded and run before any other content is added to the DOM).

这篇关于Chrome扩展程序可在文本显示之前替换文字,网页和Facebook文章的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆