尽管您肯定是朝着正确的方向(实际上接近末尾),但是代码中存在几种(imo)不良做法(例如,为这样的琐碎任务注入整个库(jquery),声明不必要的权限,变得多余)调用API方法等)。
我没有亲自测试您的代码,但是从快速的概览中,我相信更正以下内容可能会导致一个可行的解决方案(尽管不是非常接近最佳):
- 在 manifest.json中 :更改内容脚本的顺序,将jquery放在首位。根据 相关文档 :
“ js” […]将注入匹配页面的Javascript文件列表。这些 以它们 在此数组中 出现的顺序 注入。
(强调我的)
- 在 contentscript.js :移动 chrome.runtime.sendMessage({…}) 块 内 的
onMessage
听者回调。
也就是说,这是我建议的方法:
控制流:
- 内容脚本将被注入到每个符合某些条件的页面中。
- 注入后,内容脚本会将消息发送到事件页面(又称非持久性背景页面),事件页面会将页面操作附加到选项卡。
- 加载页面操作弹出窗口后,它将立即向内容脚本发送一条消息,询问其所需的信息。
- 内容脚本处理请求,并做出响应,以便页面操作弹出窗口可以显示信息。
目录结构:
root-directory/|_____img |_____icon19.png |_____icon38.png|_____manifest.json|_____background.js|_____content.js|_____popup.js|_____popup.html
manifest.json:
{ "manifest_version": 2, "name": "Test Extension", "version": "0.0", "offline_enabled": true, "background": { "persistent": false, "scripts": ["background.js"] }, "content_scripts": [{ "matches": ["*://*.stackoverflow.com/*"], "js": ["content.js"], "run_at": "document_idle", "all_frames": false }], "page_action": { "default_title": "Test Extension", //"default_icon": { // "19": "img/icon19.png", // "38": "img/icon38.png" //}, "default_popup": "popup.html" } // No special permissions required... //"permissions": []}background.js:
chrome.runtime.onMessage.addListener((msg, sender) => { // First, validate the message's structure. if ((msg.from === 'content') && (msg.subject === 'showPageAction')) { // Enable the page-action for the requesting tab. chrome.pageAction.show(sender.tab.id); }});content.js:
// Inform the background page that // this tab should have a page-action.chrome.runtime.sendMessage({ from: 'content', subject: 'showPageAction',});// Listen for messages from the popup.chrome.runtime.onMessage.addListener((msg, sender, response) => { // First, validate the message's structure. if ((msg.from === 'popup') && (msg.subject === 'DOMInfo')) { // Collect the necessary data. // (For your specific requirements `document.querySelectorAll(...)` // should be equivalent to jquery's `$(...)`.) var domInfo = { total: document.querySelectorAll('*').length, inputs: document.querySelectorAll('input').length, buttons: document.querySelectorAll('button').length, }; // Directly respond to the sender (popup), // through the specified callback. response(domInfo); }});popup.js:
// Update the relevant fields with the new data.const setDOMInfo = info => { document.getElementById('total').textContent = info.total; document.getElementById('inputs').textContent = info.inputs; document.getElementById('buttons').textContent = info.buttons;};// once the DOM is ready...window.addEventListener('DOMContentLoaded', () => { // ...query for the active tab... chrome.tabs.query({ active: true, currentWindow: true }, tabs => { // ...and send a request for the DOM info... chrome.tabs.sendMessage( tabs[0].id, {from: 'popup', subject: 'DOMInfo'}, // ...also specifying a callback to be called // from the receiving end (content script). setDOMInfo); });});popup.html:
<!DOCTYPE html><html> <head> <script type="text/javascript" src="popup.js"></script> </head> <body> <h3 >DOM Info</h3> <table border="1" cellpadding="3" > <tr> <td nowrap>Total number of elements:</td> <td align="right"><span id="total">N/A</span></td> </tr> <tr> <td nowrap>Number of input elements:</td> <td align="right"><span id="inputs">N/A</span></td> </tr> <tr> <td nowrap>Number of button elements:</td> <td align="right"><span id="buttons">N/A</span></td> </tr> </table> </body></html>



