JavaScript类setAttribute应用于Chrome扩展程序

3
我正试图通过Google Chrome扩展程序更改任何Google搜索中的标题条目属性。 所谓的标题条目是指这些红色下划线: 图片: http://postimg.org/image/sgsyccbpf/ 通过Mozilla Firefox检查器查看随机Google搜索的HTML代码: 图片: http://postimg.org/image/gsywhsmkj/ 我的想法是通过查找类名“rc”获取每个元素。也许这不是一个好主意,但我认为它会起作用。
为了开发Chrome扩展程序,我编写了以下文件:

manifest.json

{
    "name": "Test  1",
    "version": "1.0.0",
    "manifest_version": 2,
    "content_scripts": [
        {
            "matches": [
                "https://*/*",
                "http://*/*",
                "<all_urls>"
            ],
            "js":         ["content_scripts.js"],
            "run_at":     "document_start",
            "all_frames": true
        }
    ]
}

content:scripts.js

var doFilter = function() { 
    var classR = document.getElementsByClassName("rc");

    for(var i=0; i < classR.length; i++) { 
        classR[i].setAttribute("style", "background-color:green"); 
        classR[i].setAttribute("align", "center");
    }
}

window.addEventListener("DOMContentLoaded", function() {
    doFilter(document.body);
});

这是我的扩展在自己的HTML页面中运作的演示: 图像: postimg.org/image/bdi02zvfl(这是一个链接到图像,但系统不允许我发布超过两个)
然而,在正常搜索Google时它不起作用。每个“标题条目”都应该像演示中那样有绿色背景并居中。
我错过了什么?
谢谢!

我已经标记了你在提到的帖子中非常准确的解决方案为已接受。现在我也标记了这个。谢谢。 - user2957378
3个回答

2
由于Google异步获取结果,因此您可以使用MutationObserver来捕获DOM中的更改并相应地采取措施。请参见此答案以获得更详细的说明和示例代码。

下面是来自上述问题的代码,经过一些修改以实现您所需的内容。编辑modifyElem()函数,应该很容易实现任何修改。

content.js:

console.log("Injected...");

/* MutationObserver configuration data: Listen for "childList"
 * mutations in the specified element and its descendants */
var config = {
    childList: true,
    subtree: true
};

/* Traverse 'rootNode' and its descendants and modify '.rc' elements */
function modifyElems(rootNode) {
    var nodes = [].slice.call(rootNode.querySelectorAll('.rc'));
    if (rootNode.className === 'rc') {
        nodes.push(rootNode);
    }
    while (nodes.length > 0) {
        var st = nodes.shift().style;
        st.backgroundColor = 'green';
        st.textAlign = 'center';
    }
}

/* Observer1: Looks for 'div#search' */
var observer1 = new MutationObserver(function(mutations) {
    /* For each MutationRecord in 'mutations'... */
    mutations.some(function(mutation) {
        /* ...if nodes have beed added... */
        if (mutation.addedNodes && (mutation.addedNodes.length > 0)) {
            /* ...look for 'div#search' */
            var node = mutation.target.querySelector("div#search");
            if (node) {
                /* 'div#search' found; stop observer 1 and start observer 2 */
                observer1.disconnect();
                observer2.observe(node, config);

                /* Modify any '.rc' elements already in the current node */
                modifyElems(node);

                return true;
            }
        }
    });
});

/* Observer2: Listens for element insertions */
var observer2 = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        if (mutation.addedNodes) {
            [].slice.call(mutation.addedNodes).forEach(function(node) {
                if (node.nodeType === Node.ELEMENT_NODE) {
                    modifyElems(node);
                }
            });
        }
    });
});

/* Start observing 'body' for 'div#search' */
observer1.observe(document.body, config);

1
你的doFilter()函数只在页面初始加载时运行一次,这意味着如果Google使用AJAX(通常会这样做)加载任何结果,你的代码将不会对它们产生影响。
你的扩展程序可以添加一个<style>元素到页面头部,以实现你想要的样式。
<style>
.rc { background-color: green; text-align: center; }
</style>

这样做的另一个好处是不会破坏目标元素可能已经存在的任何style属性。

我用你写的代码创建了一个名为mystyles.css的文件,并在清单中添加了一行*"css":["mystyle.css"],*,但它没有起作用。然而,在我们采用这个解决方案之前,我应该说一下我的最终目标将包括对"class"rc"进行另一个检查,因此我肯定需要在javascript中评估它。有没有办法在AJAX代码已经执行时执行脚本? - user2957378

0
$(window).load(function() {
    doFilter(document.body);;
});

改为:

window.addEventListener("DOMContentLoaded", function() {
    doFilter(document.body);
});

问题已解决。 我还需要下载jquery.js库文件并在此处引用它的清单:

"js":         ["jquery.js", "content_scripts.js"],

在处理jQuery函数时,存在很多混淆。据我所读,$(window).load()是在页面完全创建后执行的函数。 参考资料:jQuery - What are differences between $(document).ready and $(window).load? 感谢@JLRishe的回复。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接