Ответ 1
Хотя вы определенно находитесь в правильном направлении (и на самом деле довольно близки к концу), в вашем коде существует несколько (imo) плохих практик (например, для инъекции целой библиотеки (jquery) для такой тривиальной задачи, объявления ненужных разрешений, делая суперплошные вызовы API-методам и т.д.).
Я сам не тестировал ваш код, но из краткого обзора считаю, что исправление следующего может привести к созданию рабочего решения (хотя и не очень близкого к оптимальному):
-
В manifest.json: измените порядок скриптов содержимого, сначала установите jquery. Согласно соответствующие документы:
"js" [...] Список файлов JavaScript, которые будут вставляться в соответствующие страницы. Они вводятся в порядке их появления в этом массиве.
(выделение мое)
-
В contentcript.js: переместите chrome.runtime.sendMessage({...}) блок внутри
onMessage
обратный вызов слушателя.
Итак, вот мой предложенный подход:
Управляющий поток:
- Содержимое script вводится на каждую страницу, соответствующую некоторым критериям.
- После ввода скрипты содержимого отправляют сообщение на страницу событий (непостоянная фоновая страница), а страница событий присоединяет к этой странице страницу = действие.
- Как только всплывающее окно действия страницы загружается, оно отправляет сообщение в контент script, запрашивая информацию, которая ему нужна.
- Содержимое script обрабатывает запрос и отвечает так, чтобы всплывающее окно с информацией о странице могло отображать информацию.
Структура каталогов:
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(function (msg, sender) {
// First, validate the message 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(function (msg, sender, response) {
// First, validate the message structure
if ((msg.from === 'popup') && (msg.subject === 'DOMInfo')) {
// Collect the necessary data
// (For your specific requirements `document.querySelectorAll(...)`
// should be equivalent to jquery `$(...)`)
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
function 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', function () {
// ...query for the active tab...
chrome.tabs.query({
active: true,
currentWindow: true
}, function (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 style="font-weight:bold; text-align:center;">DOM Info</h3>
<table border="1" cellpadding="3" style="border-collapse:collapse;">
<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>