如何在页面完全加载后执行内容脚本

8
我正在尝试编写一个Google Chrome扩展程序,通过类名获取页面中的元素。我的想法是使用内容脚本来获取这些元素,并将消息传递给扩展程序和弹出窗口。然而,我的内容脚本总是在整个页面加载完成之前执行,因此我无法获取想要的元素。我尝试使用window.loadeddocument.loaded ,但它们都没有起作用。我还尝试等待一段时间间隔,但脚本总是在完全相同的停止点结束执行。
// 我的内容脚本
if (document.readyState == "complete"){
    var board_name_arr = [];
    var node = document.getElementsByClassName('Board');

    for (var i = 0; i < node.length; ++i){
        var board_name = node[i].getElementsByClassName('boardName')[0].textContent;
        board_name_arr[i] = board_name;
    }

    if (Object.keys(board_name_arr).length){
        alert("found board");
    }
}

有没有一种方法可以强制它在之后运行?或者我不应该使用内容脚本的方法吗?

可能与此重复:https://dev59.com/I2Yr5IYBdhLWcg3wJ3CU - Dayton Wang
4个回答

11
可能页面通过AJAX动态加载其内容,所以当文档状态准备好时,您想要找到的元素可能尚未加载。即使某些内容在开始时已加载,更多内容可能会在之后加载。为了正确解决这个问题,我建议您使用MutationObserver技术。我在我的Chrome扩展中使用它来向每个Facebook帖子注入“收藏”按钮,效果非常好。
请参考以下代码示例:
var obs = new MutationObserver(function (mutations, observer) {
    for (var i = 0; i < mutations[0].addedNodes.length; i++) {
        if (mutations[0].addedNodes[i].nodeType == 1) {
            $(mutations[0].addedNodes[i]).find(".userContentWrapper").each(function () {
                injectFBMButton($(this));
            });
        }
    }
    injectMainButton();
});
obs.observe(document.body, { childList: true, subtree: true, attributes: false, characterData: false });

那正是我需要的。谢谢。 - R. Gurung

4

如果没有jQuery,你可以在页面加载事件上定义一个回调函数来实现。可以按照以下方式进行:

var loadfunction = window.onload;
window.onload = function(event){
    //enter here the action you want to do once loaded

    if(loadfunction) loadfunction(event);
}

或者这样做:
window.addEventListener("load", function load(event){
    window.removeEventListener("load", load, false); //remove listener, no longer needed
    //enter here the action you want to do once loaded 
},false);

这个可行!我用了第一个,但是我不太理解回调函数。它会等待所有页面加载完毕,如果没有加载完毕就再次调用该函数吗? - Irene Yeh
window.onload 是一个事件,它意味着页面加载后只调用一次。您可以在此处 http://www.quirksmode.org/js/introevents.html 或互联网上获取更多有关事件的信息。 - NeoPix
建议查看 content_scripts 的 run_at 选项。对您的问题有用,https://developer.chrome.com/extensions/content_scripts#run_time - Satya Kalluri

1

我知道这个问题已经发布很久了。 不过,希望对像我一样的人有所帮助。

Chrome扩展程序的ContentScript有一个名为run_at的选项,其中包括document_start、document_idle和document_end等选项。 文档:https://developer.chrome.com/extensions/content_scripts#run_time

.
.
.
  "content_scripts": [
    {
      "js": ["PATH_TO_YOUR_SCRIPT.JS"],
      "run_at": "document_end"
    }
  ]
.
.
.

这正是你所需要的(是manifest.json文件的部分内容)。


-5

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