Google搜索结果页面如何知道结果? [英] How to know when Google search results page renders its results?

查看:139
本文介绍了Google搜索结果页面如何知道结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在撰写Chrome扩展程序,将脚本注入Google的搜索结果页面,并修改了所有结果的锚点元素。

I'm writing a Chrome extension that injects scripts to the Google's search result page and modified all the results' anchor elements.

我的问题是结果以异步方式呈现,并且在文档加载/就绪页面上未显示。

My problem is that the results are rendered asynchronously and are not shown in the page on document load/ready.

我有两个初始解决方案不起作用:

I had 2 initial solutions which don't work:


  1. 设置一个超时:不好的做法,但它的工作原理。不过,可能会显示不一致的结果,所以我宁愿避免这种解决方案。

  1. Set a timeout: Bad practice but it works. Nevertheless, might show inconsistent results so I prefer to avoid this solution.

绑定到'DOMNodeInserted'。通常工作,但在我的情况下更复杂,因为我在锚点之前插入新的节点,这触发了一个递归。我可以插入代码以避免它,如果锚已经被'标记',但是再次,这个解决方案是坏的,因为我需要遍历所有的锚点每次插入一个节点 - 从我检查这发生在140多次在搜索结果页。

Bind to 'DOMNodeInserted'. Generally works, but more complicated in my case because I insert new nodes my self before the anchors, which triggers a recursion. I can insert code to avoid it if the anchor is already 'tagged', but again, this solution is bad since I need to traverse all the anchors each time a node is inserted - from what I checked this happens more than 140 times in the search result page.

Google在搜索结果页上是否有任何类型的自定义事件触发?在这种情况下是否有任何其他DOM事件可以工作?

Is there any kind of custom event Google trigger on the search results page? Is there any other DOM event that can work in this case?

推荐答案

你是正确的,使用DOMNodeInserted不是好办法如果没有别的,它是过时的一部分 突变事件API ,由于众所周知的效率低下,已被弃用(除其他原因之外)。

You are right in that using "DOMNodeInserted" is not a good approach. If nothing else, it is part of the obsolete Mutation Events API, which has been deprecated (among other reasons) for being notoriously inefficient.

已被strong> MutationObserver API ,所以这是什么你应该改用您可以使用 MutationObserver 在根节点及其后代观察childListDOM突变。

(如果您选择此方法, 突变概要库 也可能派上用场。)

It has been replaced by the MutationObserver API, so this is what you should use instead. You can utilize a MutationObserver to observe "childList" DOM mutations on a root node and its descendants.
(If you choose this approach the mutation-summary library might also come in handy.)

经过(真的很浅)的搜索,我发现(至少对我来说)Google将其结果放在一个 div 中, id search 。以下是执行以下操作的示例扩展的代码:

After a (really shallow) search, I found out that (at least for me) Google places its results in a div with id search. Below is the code of a sample extension that does the following:


  1. 注册MutationObserver以检测插入 div#search 到DOM中。

注册一个MutationObserver来检测中的childList div#search 及其后代。

Registers a MutationObserver to detect "childList" changes in div#search and its descendants.

每当< a> 节点,一个函数遍历相关节点并修改链接。 (由于明显的原因,该脚本忽略< script> 元素。)

Whenever a <a> node is added, a function traverses the relevant nodes and modifies the links. (The script ignores <script> elements for obvious reasons.)

此示例扩展名仅包含 ~~ 中的链接文本,但您可以轻松地更改它,以执行所需的任何操作。

This sample extension just encloses the link's text in ~~, but you can easily change it to do whatever you need.

manifest.json:

{
    "manifest_version": 2,
    "name":    "Test Extension",
    "version": "0.0",

    "content_scripts": [{
        "matches": [
            ...
            "*://www.google.gr/*",
            "*://www.google.com/*"
        ],
        "js":         ["content.js"],
        "run_at":     "document_end",
        "all_frames": false
    }],

}

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
};
var regex = /<a.*?>[^<]*<\/a>/;

/* Traverse 'rootNode' and its descendants and modify '<a>' tags */
function modifyLinks(rootNode) {
    var nodes = [rootNode];
    while (nodes.length > 0) {
        var node = nodes.shift();
        if (node.tagName == "A") {
            /* Modify the '<a>' element */
            node.innerHTML = "~~" + node.innerHTML + "~~";
        } else {
            /* If the current node has children, queue them for further
             * processing, ignoring any '<script>' tags. */
            [].slice.call(node.children).forEach(function(childNode) {
                if (childNode.tagName != "SCRIPT") {
                    nodes.push(childNode);
                }
            });
        }
    }
}

/* 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);

                if (regex.test(node.innerHTML)) {
                    /* Modify any '<a>' elements already in the current node */
                    modifyLinks(node);
                }
                return true;
            }
        }
    });
});

/* Observer2: Listens for '<a>' elements insertion */
var observer2 = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        if (mutation.addedNodes) {
            [].slice.call(mutation.addedNodes).forEach(function(node) {
                /* If 'node' or any of its desctants are '<a>'... */
                if (regex.test(node.outerHTML)) {
                    /* ...do something with them */
                    modifyLinks(node);
                }
            });
        }
    });
});

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

这篇关于Google搜索结果页面如何知道结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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