Обходной путь для манифеста версии 3
Я работал над расширением Chrome, которое включало всплывающее окно и сценарий контента; используя action.onClicked
. Я ожидал, что пользователь щелкнет значок на панели расширений. Затем событие щелчка откроет всплывающее окно, вызовет сценарий контента и позволит пользователю получить доступ к текущей веб-странице.
Когда я щелкнул значок, всплывающее окно открылось правильно, но сценарий содержимого выполнялся не синхронно. Я попытался напрямую сослаться на сценарий содержимого во всплывающем окне, но затем логика сценария выполнялась в рамках HTML всплывающего окна, не на веб-странице.
Они работали независимо, почему бы им не работать в тандеме? Ну, как выясняется…
Событие action.onClicked не будет отправлено, если в расширении указано всплывающее окно, которое будет отображаться при нажатии на текущую вкладку. — Документы для разработчиков Chrome
Поэтому возникает вопрос: как мне заставить мой скрипт содержимого выполняться только при открытии всплывающего окна? Чтобы ответить на этот вопрос, нам нужно понять, что такое контент-скрипт.
Сценарии контента — это файлы, которые запускаются в контексте веб-страниц… они могут считывать сведения о веб-страницах, которые посещает браузер, вносить в них изменения и передавать информацию своему родительскому расширению. — Документы для разработчиков Chrome
Во-первых, чтобы использовать скрипт содержимого в своем расширении, вам нужно объявить его в файле manifest.json
. См. ниже.
"content_scripts": [ { "matches": ["<all_urls>"], "css": ["my.css"], "js": ["content.js"] } ],
Это объявление может связать ваш JavaScript, CSS и многое другое с вашей веб-страницей. В приведенном выше случае content.js
и my.css
оба имеют доступ к вашей веб-странице. Это то, что мы хотим!
Однако мы хотим, чтобы он обращался к веб-странице и выполнял логику при открытии всплывающего окна.
Как написано выше, так не пойдет.
content.js
будет работать, когда веб-страница простаивает. Если вы хотите указать другое время для его запуска, вы можете использовать свойство runAt
. Вы можете добавить его в свойство content_script
, как показано ниже.
"content_scripts": [ { "matches": ["<all_urls>"], "css": ["my.css"], "js": ["content.js"], "run_at": "document_start" //right here } ],
Вы можете выбрать из document_start
, document_idle
и document_end
. Я подробнее расскажу об этом в следующем посте. На данный момент все, что нам нужно знать, это то, что проблема с этими параметрами заключается в том, что ни один из них не выполняется при открытии всплывающего окна.
Итак, как мы можем это сделать?
Что ж, мы можем просто… не объявлять никаких content_scripts
.
Я знаю, о чем вы могли подумать… ЭТО БЕЗУМИЕ.
No…
Хорошо, если серьезно, выслушайте меня.
Вместо объявления скриптов контента мы можем внедрить скрипт когда захотим. Мы можем сделать это, используя chrome.scripting
.
Возможно, вы помните это из моего предыдущего поста о фоновых скриптах. Мы будем делать то же самое, но на этот раз с JavaScript нашего всплывающего окна.
Во-первых, в вашем файле manifest.json
вам нужно указать разрешения scripting
, чтобы разрешить выполнение сценариев. См. наши последние manifest
ниже.
{ "name": "Popup and Content Script", "description": "How to use a content script with a popup", "version": "1.0.0", "manifest_version": 3, "permissions": [ "scripting", ], "host_permissions": [ "<all_urls>" ], "action":{ "default_title": "Popup and Content Script", "default_popup": "popup.html" } }
Обратите внимание, как мы удалили объявление content_scripts
. Нам больше не нужно ссылаться на него, так как мы будем внедрять его.
Получите весь мой последний контент, создав учетную запись в партнерской программе Medium и подписавшись на мои электронные письма. :)
Затем мы можем начать работать с файлом JavaScript нашего всплывающего окна, popup.js
. Ради краткости я не буду освещать HTML-сторону в этом посте. Все, что вам нужно знать, это то, что вы должны указать popup.js
в конце тега body
в popup.html
.
Весь код для этого поста можно найти на GitHub.
В popup.js
мы будем писать логику, используемую для вызова нашего импровизированного сценария контента (content.js
). Здесь нам понадобится вкладка текущей страницы.
Вот функция, которую мы можем использовать для этого.
getCurrentTab = async () => { let queryOptions = { active: true }; let [tab] = await chrome.tabs.query(queryOptions); return tab; }
chrome.tabs.query...
вернет Promise
. Чтобы получить доступ к результирующему tab
внутри Promise
, мы можем вызвать getCurrentTab
внизу popup.js
.
getCurrentTab().then((tab)=>{ injectContentScript(tab) })
Теперь, когда мы это настроили, мы можем начать писать логику для injectContentScript
в верхней части popup.js
. Эта функция будет использовать executeScript
для внедрения скрипта содержимого при открытии всплывающего окна.
injectContentScript = (tab) => { const {id, url} = tab; chrome.scripting.executeScript( { target: {tabId: id, allFrames: true}, files: ['content.js'] } ) console.log(`Loading: ${url}`); }
Идеальный! Наш executeScript
теперь внедряет наш скрипт content.js
на нашу веб-страницу. Теперь, когда мы установили это соединение, мы наконец можем начать писать content.js
.
В этом файле мы напишем простой скрипт, который просто устанавливает белый цвет всех тегов p
на текущей странице, а также применяет красную рамку. Мы можем назвать эту функцию whiteout
. См. ниже.
whiteout = () => { var ptags = document.getElementsByTagName("p") for (var i = 0; i < ptags.length; ++i){ ptags[i].style.color = "white" ptags[i].style.border = "solid 1px red" } } whiteout()
Довольно просто, нет? Давайте проверим это!
Просто перейдите на chrome://extensions/ и загрузите распакованный проект. Включите расширение в своем браузере, а затем нажмите на него, чтобы попробовать! Вам следует…
- Увидеть всплывающее окно с указанным содержимым
- Посмотрите, как теги
p
на вашей текущей веб-странице «забелены»
Вот так выглядит мой.
Вот оно! Теперь у вас есть сценарий содержимого, который выполняется, когда вы открываете всплывающее окно расширения Chrome. Это может быть полезно, когда вам нужно передать содержимое веб-страницы во всплывающее окно, чтобы пользователь мог видеть показатели или статистику или… просто поиграть со стилем.
Следите за моим следующим постом, в котором я более подробно расскажу о сценариях контента! И снова весь сопроводительный код к этому посту можно найти на GitHub.
Какие классные расширения для Chrome вы сделали? Дай мне знать в комментариях!
Обновите бесплатную подписку на Medium и получайте неограниченное количество статей без рекламы от тысяч авторов в самых разных изданиях. Это партнерская ссылка, и часть вашего членства помогает мне получать вознаграждение за контент, который я создаю.
Вы также можете подписаться по электронной почте и получать уведомления, когда я публикую что-то новое!
Рекомендации
chrome.scripting — Chrome Developers
Чтобы использовать chrome.scripting API, вам необходимо указать «manifest_version 3 или выше и включить…разработчик.chrome.com»