如何在Chrome扩展程序中从background.js引用popup.html DOM?

时间:2018-12-06 03:08:13

标签: javascript html google-chrome-extension

我正在尝试在弹出窗口关闭时保存我的弹出html的副本。然后在再次触发弹出窗口时重新加载它。 background.js侦听与popup.js断开的端口。但是,当我尝试获取popup.html时,我想我正在获取background.html(即使我从未设置过)。

background.js

chrome.runtime.onConnect.addListener(function (externalPort) {
    externalPort.onDisconnect.addListener(function () {
        let page = document.getElementsByTagName('html')[0].innerHTML;
        console.log(page);
        chrome.storage.local.set({"page": page});
    })
});

记录的内容

<head></head><body>
<script src="jquery-3.3.1.min.js"></script>
<script src="popup.js"></script>
<script src="background.js"></script>
</body>

当我从popup.js中获取innerHTML时,我获得了正确的html,但我不知道如何从background.js中正确引用它。

编辑:popup.html

<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Treasure Roller</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" type="text/css" media="screen" href="style.css" />
    <script src="jquery-3.3.1.min.js"></script>
    <script src="popup.js"></script>
</head>

2 个答案:

答案 0 :(得分:1)

您可能遇到的第一个挑战是将后台脚本加载到弹出窗口中。即使您的后台脚本是在清单文件中声明的,您也可能会遇到一些问题。因为chrome会将其视为popup.html的一部分。

这意味着:

  1. 您的popup.jsbackground.js(在弹出窗口中加载)之间没有通信。

  2. 可能会发生错误,导致您无法从弹出式上下文中运行javascript。这是因为当正确使用background.js时,其访问chrome APIs的权限比弹出窗口要多。如果在弹出上下文中使用并且调用了这些API,则将引发异常。当引发异常但未捕获到异常时,脚本将暂停,以防止您执行任何其他涉及js的操作。除非您有一个不是背景页面的background.js文件,否则不应将background.js加载到popup.html中。

您可以确定是否属于这种情况,是在弹出页面上单击鼠标右键,然后单击“检查”。转到控制台选项卡,并阅读可能发生的任何错误。如果没有发生错误,我仍然建议您从popup.html中删除background.js脚本。

顺便说一句,不需要将后台脚本加载到任何html页面中。它甚至会在用户输入网址之前自动在浏览器启动时运行。

如果以上都不适合您,

错误通常具有从错误发生的位置开始的堆栈跟踪。单击任何显示chrome://extensions...的内容。它应该将您带到代码中出现问题的确切位置。

如果这对您没有帮助,请进行以下测试:

popup.js

chrome.runtime.sendMessage({saveState: true, state: {---"state data goes in here---"}});

我相信您可以用这种方式发送整个html。

background.js

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse){
    if(request.saveState){
        chrome.storage.local.set(request.state, function(){ sendResponse(true)});
    }
});

简而言之,每次对弹出界面进行更改时,

(例如,用户单击您的待办事项列表扩展名上某个项目的编辑文本,它将变成输入文本框),

您将{view: "edit", item: "no 2", addButton: "hidden"}作为状态对象发送到后台,然后由其保存到存储中。

当弹出窗口打开时,您只需要向存储请求状态并根据数据呈现UI。

chrome.storage.local.get('state', function(result){
    if(result.state){
        //This is a function you will write
        render(result.state); 
    }
    else{
        //do nothing
    }
});

请注意,您还使用chrome.runtime.connect,该保留用于更长的连接。这样做没什么问题,但是如果您只需要保存状态beforeunload,则现在发送一次消息可能更易于调试。

答案 1 :(得分:0)

如果要在关闭弹出窗口时处理HTML,则可以尝试以下操作:

在弹出页面中创建一个window.onbeforeunload侦听器,在事件侦听器中读取html。您可以在侦听器中处理html或将其作为消息从侦听器发送到后台页面(使用chrome.runtime.sendMessage)