【问题标题】:Repeatedly Grab DOM in Chrome ExtensionChrome 扩展中反复抓取 DOM
【发布时间】:2014-01-04 15:34:03
【问题描述】:

我正在尝试自学如何编写 Chrome 扩展程序,但当我意识到我的 jQuery 出现故障时遇到了障碍,因为它从扩展程序页面本身获取信息,而不是像我预期的那样从选项卡的当前页面获取信息。

快速总结,我的示例扩展程序将每 x 秒刷新一次页面,查看内容/DOM,然后用它做一些事情。第一部分和最后一部分都很好,但从我所在的页面获取 DOM 已经证明非常困难,而且文档对我没有太大帮助。

您可以在这些链接中看到我目前拥有的代码:

Current manifest

Current js script

Current popup.html

如果我希望能够在 setInterval 调用的每个循环中获取 DOM,还需要做什么?我知道,例如,我需要一个内容脚本。但是我是否还需要在清单中指定背景页面?在我的扩展程序中,我需要在哪里调用内容脚本?在每次重新加载时让它与我当前的 js 文件通信的最简单/最好的方法是什么?我的内容脚本是否也希望我使用 jQuery?

我知道这些问题是基本的,回想起来对我来说似乎微不足道,但尝试完全独自探索这些问题确实令人头疼。提前致谢。

【问题讨论】:

    标签: google-chrome dom google-chrome-extension content-script message-passing


    【解决方案1】:

    为了访问网页 DOM,您需要 programmatically inject some code 进入其中(使用 chrome.tabs.executeScript())。

    也就是说,尽管可以将 DOM 作为字符串获取,将其传递回弹出窗口,将其加载到新元素中并查找所需的内容,但这是一种非常糟糕的方法(出于各种原因) .
    最好的选择(就效率和准确性而言)是在网页本身中进行处理,然后只将结果传递回弹出窗口。请注意,为了能够将代码注入网页,您必须在清单中的 permissions 属性中包含相应的 host match pattern

    我上面描述的可以这样实现:

    editorMarket.js

    var refresherID = 0;
    var currentID = 0;
    
    $(document).ready(function(){
        $('.start-button').click(function(){
            oldGroupedHTML = null;
            oldIndividualHTML = null;
    
            chrome.tabs.query({ active: true }, function(tabs) {
                if (tabs.length === 0) {
                    return;
                }
    
                currentID = tabs[0].id;
                refresherID = setInterval(function() {
                    chrome.tabs.reload(currentID, { bypassCache: true }, function() {
                        chrome.tabs.executeScript(currentID, {
                            file:      'content.js',
                            runAt:     'document_idle',
                            allFrames: false
                        }, function(results) {
                            if (chrome.runtime.lastError) {
                                alert('ERROR:\n' + chrome.runtime.lastError.message);
                                return;
                            } else if (results.length === 0) {
                                alert('ERROR: No results !');
                                return;
                            }
    
                            var nIndyJobs  = results[0].nIndyJobs;
                            var nGroupJobs = results[0].nGroupJobs;
                            $('.lt').text('Indy: ' + nIndyJobs + '; '
                                          + 'Grouped: ' + nGroupJobs);
                        });
                    });
                }, 5000);
            });
        });
    
        $('.stop-button').click(function(){
            clearInterval(refresherID);
        });
    });
    

    content.js:

    (function() {
        function getNumberOfIndividualJobs() {...}
        function getNumberOfGroupedJobs() {...}
    
        function comparator(grouped, individual) {
            var IndyJobs = getNumberOfIndividualJobs();
            var GroupJobs = getNumberOfGroupedJobs();
    
            nIndyJobs = IndyJobs[1];
            nGroupJobs = GroupJobs[1];
            console.log(GroupJobs);
    
            return {
                nIndyJobs: nIndyJobs, 
                nGroupJobs: nGroupJobs
            };
        }
    
        var currentGroupedHTML = $(".grouped_jobs").html();
        var currentIndividualHTML = $(".individual_jobs").html();
        var result = comparator(currentGroupedHTML, currentIndividualHTML);
        return result;
    })();
    

    【讨论】:

    • 忘记回复你了,抱歉!它进行了一些实验和测试,但最终我确实得到了它与您建议的非常接近的东西。谢谢!最大的问题之一是清单不会自行刷新,除非我重新加载整个扩展程序(这对我的 JS/HTML/CSS 更新而言并非如此),这很有趣。我也花了一点时间才得到正确的返回值——我的“返回值”;声明给出了一个空对象。只写“价值”;结束了工作。无论如何,非常感谢
    • 很高兴它有帮助。 return 应该在函数中使用 - 如果您删除立即调用的函数表达式,那么您确实还需要删除 return
    猜你喜欢
    • 2021-10-22
    • 2013-11-14
    • 2014-12-26
    • 1970-01-01
    • 1970-01-01
    • 2014-11-19
    • 2012-01-09
    • 1970-01-01
    相关资源
    最近更新 更多