#javascript #html #google-chrome-extension
#javascript #HTML #google-chrome-расширение
Вопрос:
У меня есть расширение Chrome, в котором пользователь вводит некоторую информацию, и оно генерирует отчет. Теперь, конечно, этот отчет будет отличаться каждый раз в зависимости от того, что ввел пользователь.
Чего я хочу добиться, так это того, чтобы мое расширение сообщало:
Привет, мистер фоновая страница. Вот необходимая вам информация, теперь создайте некоторый html на основе того, что я вам дал, и покажите его пользователю.
Вот manifest.json
, который я использую:
{
"manifest_version": 2,
"name": "XXXX",
"description": "XXXX",
"version": "1.0.0",
"permissions": ["storage", "tabs"],
"options_page": "settings.html",
"background":
{
"page": "background.html"
},
"content_scripts":
[
{
"matches": ["<all_urls>"],
"js": ["js/jquery-3.1.1.min.js", "js/bootstrap.min.js", "js/main.js", "js/background.js"],
"css": ["css/bootstrap.min.css", "css/font-awesome.min.css"]
}
],
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"icons": { "128": "logo.png" }
}
Вот мой background.html
<html>
<body>
<script src="js/jquery-3.1.1.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/background.js"></script>
</body>
</html>
И вот мой background.js
$(document).ready(function() {
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
$("body").html(msg.message);
console.log("Message from: " msg.message);
});
});
Теперь, когда пользователь нажимает кнопку на моем расширении, я использую следующий код для отправки сообщения:
$("#generate").click(function() {
chrome.tabs.create({url: 'background.html'});
chrome.runtime.sendMessage({
message: "Sample message."
});
});
Теперь я ожидал, что моя background.html
страница откроется, а затем тело страницы изменится в зависимости от того, какое сообщение было отправлено, но это не работает.
Есть идеи?
Ответ №1:
Вы совершаете огромную концептуальную ошибку, пытаясь использовать ту же страницу для фона и для отображения чего-либо. Это может привести к очень непредсказуемому поведению.
По сути, вы пытаетесь открыть вкладку с помощью background.html
и каким-то образом ожидаете, что это будет «та самая» фоновая страница. Это так не работает — вы открываете новый экземпляр того же документа. Представьте, что вы открываете одну и ту же веб-форму на двух вкладках — вы не ожидаете, что они будут отражать текст, введенный в поля.
Кроме того, накоплено много ошибок в отношении взаимодействия всплывающих страниц с открывающимися вкладками.
Итак, план действий:
-
Если вам действительно нужно, чтобы фрагмент кода выполнялся на (постоянно невидимой) фоновой странице, назовите его идиоматически
background.js
и переключитесь наscripts
определение фоновой страницы в стиле:"background": { "scripts": ["background.js"] }
Также рассмотрите возможность использования страниц событий.
-
Все, что вы используете для отображения отчета, не должно вызываться
background
ради вашего здравомыслия. Переименуйте егоreport.html
/report.js
. -
В вашем всплывающем коде ваша ошибка № 1 — это выбор времени. Вы открываете страницу, которая должна прослушать ваше сообщение, но не ждете, пока оно станет готовым к прослушиванию. Вам следует использовать обратный вызов
tabs.create
, если вы хотите убедиться, что страница действительно открыта и готова.chrome.tabs.create({url: "report.html"}, function(tab) { // Okay, now it's ready, right? Right?.. chrome.runtime.sendMessage(/*...*/); });
-
Однако это не решит проблему, поскольку открытие новой вкладки по умолчанию фокусирует ее (что, по-видимому, вам и нужно), что немедленно приводит к закрытию всплывающего окна. Вы ничего не можете сделать, чтобы предотвратить это, как только вкладка сфокусирована. Но это означает, что ваше сообщение не будет отправлено: всплывающее окно будет уничтожено до того, как это произойдет.
Итак, не полагайтесь на обмен сообщениями. Предположительно, вы можете сохранить любые данные, на которых основан ваш отчет, в хранилище. Итак, сначала установите его, затем откройте страницу отчета, где вы считываете данные и создаете отчет.
// Popup chrome.storage.local.set({foo: bar}, function() { // Storage is updated, it's showtime! chrome.tabs.create({url: "report.html"}); // And now, we die, inevitably. Goodbye, cruel world. }); // Report chrome.storage.local.get("foo", function(data) { // Oh, what joy is to have data.foo in here! });
Комментарии:
1. На самом деле,
background.js
изначально был вызванtest.js
, я забыл переименовать его ради этой темы. В любом случае, спасибо вам за эту информацию!2. Кроме того,
chrome.storage.local
означает ли это, что эти данные впоследствии уничтожаются в отличие отchrome.storage.sync
?3. Нет, это означает, что оно остается на вашем компьютере, вместо того, чтобы пытаться воспроизвести его через авторизованный аккаунт Google.
4. Я вижу. Спасибо!