Здесь есть три принципиальных проблемы.
Время отправки сообщения на вкладку
На самом деле нет хорошего дубликата этого вопроса ( это ближайший кандидат), но основная проблема, с которой вы столкнулись, - это время.
После открытия вкладки вызывается обратный вызов create
до того, как страница будет достаточно загружена.Ваш контент-скрипт может просто не быть там, чтобы прослушать сообщение.С document_end
таймингом это почти наверняка не так.
Единственный безопасный способ сделать это - перевернуть связь: пусть скрипт контента запрашивает данные, чтобы вы знали, что они готовы.
Это приводит к следующей проблеме ..
Закрытие всплывающего окна при открытии сообщения
Когда вы создаете вкладку, которая сфокусирована, это приводит к потере всплывающего окнаСфокусируйтесь и закройте.
Когда это произойдет, выполняемый там скрипт завершится - как если бы вы закрыли вкладку со страницей.
Так что остальная часть вашего кода даже не запускается(независимо от предыдущего номера).У вас есть два варианта:
Вы можете создать вкладку с установленным active: false
.Это не теряет фокус, поэтому всплывающее окно остается активным, но оно менее удобно для пользователя, хотя вы все равно можете сделать его активным после этого.
Как несвязанная заметка, вы не должны query
когда такие функции, как tabs.create
, явно возвращают объект tab
в своем обратном вызове.
Лучший вариант: вам следует делегировать сообщение открытия, затем связи на фоновую страницу,Он невосприимчив к эффекту закрытия всплывающих окон и, как правило, лучше подходит в качестве «коммуникационного маршрутизатора».
, что приводит нас к последней проблеме ..
Неправильное пониманиеархитектура фоновой страницы
Вы объявили скрипт background.js
в манифесте как фоновый скрипт.Что это значит?
Это означает, что отдельная, невидимая, пустая страница создается и загружается при запуске этого скрипта.
Если вы включаете скрипт background.js
в других местах расширенияэто не будет «тот» экземпляр скрипта.Это будет независимая копия, работающая и подчиненная всем ограничениям ее нового контекста.
Очень сильный совет: не пытайтесь повторно использовать целые сценарии в своем коде.Хорошо иметь некоторый общий код (скажем, utils.js
, содержащий некоторые общие функции и включенный перед соответствующими сценариями), но позаботьтесь о том, чтобы ваши сценарии назывались описательно и разделяли код.
Для взаимодействия с«Настоящая» фоновая страница, вам нужно отправлять сообщения (с chrome.runtime.sendMessage
).
Собрав все это вместе, ваша логика должна быть:
- Во всплывающем окне (сделайте его отдельным сценарием
popup.js
) прослушайте событие пользовательского интерфейса. - Когда это произойдет, отправьте его в фоновый режим (через message ) или сохраните(в
chrome.storage
) пользовательских данных. - Затем с помощью обмена сообщениями попросите фоновую страницу выполнить операцию.Подготовьте всплывающее окно к закрытию на этом этапе.
- Ваш фон может открыть страницу, запрошенную на этом этапе.Это убьет всплывающее окно, но вам все равно.
- Ваш скрипт контента после инициализации может либо напрямую получать пользовательские данные из
chrome.storage
, либо запрашивать их (через runtime.sendMessage
) изфоновая страница.
Существует опасение, что ваш скрипт контента запускается каждый раз, когда открывается целевая страница, даже если вы не хотите использовать пользовательские данные.Вы можете либо реализовать какой-либо механизм, чтобы использовать данные только один раз (например, очистить / пометить их после использования), или только программно внедрить скрипт содержимого (хотя у вас снова возникнут проблемы с синхронизацией после tabs.create
)