Статьи

Создание расширения Chrome за пять шагов

Сделайте простые в использовании расширения Chrome за несколько простых шагов

Прежде всего, зачем создавать расширение Chrome?

С расширением Chrome вы можете настроить свой опыт просмотра. Некоторые популярные расширения Chrome — это StayFocused (блокирующий отвлекающие веб-сайты) или AdBlock Plus (блокирующий показ рекламы).

Излишне говорить, что расширения Chrome работают только в браузерах Chrome. Посетите интернет-магазин Chrome. Он может похвастаться размещением 200 000 расширений по состоянию на середину 2019 года.

Вам также может понравиться: 17 расширений Chrome для веб-разработчиков и дизайнеров .

В этом блоге я объясню, как создать расширение на примере. Расширения просты в создании и написаны на простом старом HTML, CSS и JavaScript. Давайте начнем!

Что мы строим сегодня?

Мы создаем расширение, которое сканирует URL-адреса на странице и показывает количество исходящих ссылок на разные домены.

Чтобы усложнить задачу, давайте откроем домен с максимальными ссылками в новой вкладке. Конечный результат будет выглядеть примерно так.

Конечный результат расширения URLCount

Конечный результат расширения URLCount

Вышеуказанное расширение показывает, что текущая страница имеет 423 исходящих ссылки на developer.chrome.com, шесть исходящих ссылок на stackoverflow.com и т. Д.

Какая польза от такого расширения?

Ничего. В самом деле. Я просто хочу показать вам, как различные части работают вместе, чтобы вы могли создавать более значимые расширения самостоятельно.

Архитектура расширения

Прежде чем мы начнем вводить код, позвольте мне объяснить различные части, которые составляют функцию. С этим пониманием вы сможете понять, как работает любое расширение.

Вот полный код на случай, если вы захотите пропустить блог и перейти к поиску. Перейдите в конец этого блога, чтобы узнать, как загрузить и запустить расширение.

Расширение Chrome обычно имеет три сценария. Каждый сценарий живет в своем собственном мире и не знает других сценариев.

Фоновый скрипт (background.js) : действует слушатель событий браузера. Он имеет доступ к API расширений Chrome для таких вещей, как создание новой вкладки, и может прослушивать события браузера, такие как закрытие вкладки.

Сценарий содержимого (content.js) : имеет доступ к странице, отображаемой в браузере. Если вы хотите манипулировать DOM страницы, например, выделяя теги привязки другим цветом, вы будете использовать этот скрипт.

Сценарий пользовательского интерфейса (popup.js) : расширение может иметь свой собственный пользовательский интерфейс, и сценарий пользовательского интерфейса имеет доступ к этому пользовательскому интерфейсу.

Пользовательский интерфейс, контент и фоновые скрипты
Пользовательский интерфейс, контент и фоновые скрипты

Вы спрашиваете, если сценарии живут в своем собственном контексте, как они общаются друг с другом?

Answer: Message Passing. 

Сообщение может содержать действительный объект JSON.

Давайте применим теорию к нашему расширению

  1. Наше расширение имеет пользовательский интерфейс, который показывает все исходящие ссылки и количество таких исходящих ссылок на домен. Итак, у нас будет HTML-файл, скажем, popup.html.
  2. Popup.html нужен компаньон popup.js для динамического добавления доменных имен в DOM popup.html.
  3. Content.js требуется, чтобы прочитать текущую активную страницу и получить все ссылки на странице. content.js сделает это после получения сообщения от popup.js для получения URL-адресов.
  4. Как только content.js извлекает все URL, он передает данные в popup.js через сообщение.
  5. Popup.js отправляет домен с максимальным количеством ссылок на background.js через, как вы уже догадались, сообщение.
  6. Background.js использует chrome API для открытия новой вкладки с именем домена, переданным в форме popup.js.

Файловая структура

Расширение будет иметь следующую структуру файлов. Следуйте приведенным ниже инструкциям, чтобы создать их по одному или скачать код здесь .

URLCount
|- manifest.json
|- icon16.png
|- icon48.png
|- icon128.png
|- popup.html
|- popup.js
|- jquery-3.4.1.min.js
|- background.js
|- content.js

Создайте папку с именем URLCount. Давайте поместим все наши файлы в эту папку.

Шаг первый: Manifest.json

Создайте файл manifest.json и поместите в него следующий код.

//manifest.json

{
"manifest_version": 2,
"name": "URLCount",
"description": "Sample extension to show URL count in a page",
"version": "1.0"
}

Файл Manifest.json содержит информацию о расширении, такую ​​как имя расширения, номер версии, разрешения, требуемые расширением, и т. Д.

Шаг второй: добавить значки

Наше расширение имеет значок, связанный с ним. Давайте добавим значок в папку URLCount.

Значок расширения рядом с адресной строкой.  Это действует как триггер.
Значок расширения рядом с адресной строкой

Руководство разработчика Chrome рекомендует добавлять один и тот же значок в разрешениях 16, 48 и 128 пикселей. Идите вперед и возьмите значок, который доступен в этих трех резолюциях.


Обновите файл manifest.json для этих значков.
//manifest.json

{
"manifest_version": 2,
"name": "URLCount",
"description": "Sample extension to show URL count in a page",
"version": "1.0",
"icons": {
 "128": "icon128.png",
 "48": "icon48.png",
 "16": "icon16.png"
 }
}

Шаг третий: Пользовательский интерфейс расширения

Теперь пришло время создать интерфейс расширения — popup.html.

Интерфейс расширения
Интерфейс расширения

Конечно, мы должны поместить этот файл в manifest.json. Мы хотим показать этот интерфейс после нажатия на значок. Этот тип расширения называется действием браузера . Существует другой тип расширения, называемый расширением действия страницы. Мы обсудим это в другой раз.

//manifest.json

{
"manifest_version": 2,
"name": "URLCount",
"description": "Sample extension to show URL count in a page",
"version": "1.0",
"icons": {
 "128": "icon128.png",
 "48": "icon48.png",
 "16": "icon16.png"
},

"browser_action": {
 "default_icon": "icon16.png",
 "default_popup": "popup.html"
 }
}

Из пользовательского интерфейса вы можете видеть, что вам просто нужна таблица в HTML. Давайте также добавим идентификатор в таблицу с именем tabs_table. popup.js будет использовать этот идентификатор для заполнения таблицы. Создайте popup.html и поместите код ниже.

<!DOCTYPE html>
<html>
<head>
   <title>URLCount</title>
</head>
<body>
   <table id=”tabs_table”>
       <tbody>
           <tr></tr>
       </tbody>
   </table>
</body>
</html>

Поскольку домены будут добавляться в HTML динамически, для этого нам понадобится popup.js. Давайте использовать jquery, чтобы сделать нашу жизнь проще. Загрузите последний файл jquery min и поместите его в ту же папку. Обновите HTML так.

<head>
   <title>URLCount</title>
   <script src="jquery-3.4.1.min.js"></script>
   <script src="popup.js"></script>
</head>

Здесь следует отметить, что мы не будем добавлять popup.js в manifest.json.

Первой задачей popup.js является отправка сообщения в скрипт контента для получения доменов. Создайте файл popup.js и поместите в него следующий код.

//popup.js

$(function() {
 // Send a message to content.js to fetch all the top domains
 chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
   var activeTab = tabs[0];
   chrome.tabs.sendMessage(activeTab.id, {"message": "fetch_top_domains"});
 });
});

  1. Chrome.tabs API используется для создания, закрытия или изменения порядка вкладок. chrome.tabs.query — это асинхронный API, который возвращает все вкладки, соответствующие заданным свойствам. Мы ищем активную вкладку в текущем окне.
  2. Chrome.tabs.sendMessage отправляет любые данные на выбранную вкладку. Давайте отправим сообщение «fetch_top_domains» в скрипт контента, чтобы запустить сбор URL-адресов.

Мы еще не закончили с popup.js. Давайте сначала посмотрим, как fetch_top_domains обрабатывается скриптом содержимого.

Шаг четвертый: контент-скрипт

Наш контент-скрипт должен прослушивать сообщение fetch_top_domains. После обработки fetch_top_domains, он должен отправить сообщение сценарию пользовательского интерфейса, что он завершил свою работу. Давайте назовем это второе сообщение all_urls_fetched.

Прежде чем мы напишем content.js, давайте обновим manifest.json.

//manifest.json

"content_scripts": [
 {
 "matches": ["<all_urls>"],
 "js": ["content.js"]
 }
]

Выражение «match» указывает Chrome загружать content.js для всех страниц. Вы можете сделать так, чтобы content.js запускался в твиттере, например: «совпадения»: [«https://twitter.com/*»]

После обновления manifest.json создайте content.js в той же папке и поместите следующий код.

//content.js

chrome.runtime.onMessage.addListener(
 function(request, sender, sendResponse) {
   if( request.message === "fetch_top_domains" ) {
// Handle the message
chrome.runtime.sendMessage({"message": "all_urls_fetched"});
    }
  }
);

chrome.runtime.sendMessage отправляет одно сообщение слушателям событий.

Наряду с сообщением all_urls_fetched, скрипт контента должен также отправлять полезную нагрузку. Полезная нагрузка должна содержать все домены и количество ссылок на каждый домен.

Давайте использовать document.links, чтобы получить все ссылки со страницы и проанализировать их. Окончательный код будет выглядеть следующим образом.

// content.js

chrome.runtime.onMessage.addListener(
 function(request, sender, sendResponse) {
   if( request.message === "fetch_top_domains" ) {
     var urlHash = {}, links = document.links;
     for(var i=0; i<links.length; i++) {
       var domain = links[i].href.split('/')[2]
       if (urlHash[domain]) {
         urlHash[domain] = urlHash[domain] + 1;
       }
       else {
         urlHash[domain] = 1;
       }
     }
     chrome.runtime.sendMessage({"message": "all_urls_fetched", "data": urlHash});
   }
 }
);

Теперь пришло время обработать all_urls_fetched в popup.js.

//popup.js

chrome.runtime.onMessage.addListener(
 function(request, sender, sendResponse) {
   if( request.message === "all_urls_fetched" ) {
   }
  }
);

Добавьте логику для анализа urlHash, отправленного content.js, и найдите домен, на который есть максимальное количество ссылок. Кроме того, добавьте содержимое urlHash в tabs_table в popup.html.

//popup.js

if( request.message === "all_urls_fetched" ) {
 var urlWithMaxLinks;
 var maxLinks = 0;

 for ( var key in request.data ) {
   if(request.data.hasOwnProperty(key)) {
     $('#tabs_table tr:last').after('<tr><td>' + key + '</td>' + '<td>' + request.data[key] +'</td></tr>');

     if(request.data[key] > maxLinks) {
       maxLinks = request.data[key];
       urlWithMaxLinks = key;
     }
   }
 }
}

Мы почти на месте. Как мы будем открывать urlWithMaxLinks в новой вкладке?

Введите фоновый скрипт. Давайте отправим сообщение из popup.js в chrome runtime с urlWithMaxLinks в качестве полезной нагрузки.

if ( maxLinks != 0 ) {
 chrome.runtime.sendMessage({"message": "open_max_url", "url": urlWithMaxLinks});
}

Шаг пятый: фоновый скрипт

Пришло время обновить manifest.json информацией о background.js. Поскольку мы будем открывать новую вкладку с помощью urlWithMaxLinks, давайте дадим разрешение вкладкам .

//manifest.json

"permissions": ["tabs"],
"background": {
 "scripts": ["background.js"]
}

background.js listens to open_max_url and uses chrome.tabs API to create a new tab with the URL in the payload. chrome.tabs.create does not work without http:// or https:// (remember, we removed it in popup.js). Let’s add an http:// for simplicity before create is called.

//background.js

chrome.runtime.onMessage.addListener(
 function(request, sender, sendResponse) {
   if( request.message === "open_max_url" ) {
     fullURL = "http://" + request.url;
     chrome.tabs.create({"url": fullURL, "active": false});
   }
 }
);

Testing the Extension

It’s time to load our extension and test.

  1. Go to chrome://extensions.
  2. Enable «Developer mode.»
  3. Click on «Load unpacked.»
  4. Select your extension folder.

Как загрузить расширение Chrome?

How to load a chrome extension

How to load a Chrome extension?

Please check out the chrome extension developer guide for in-depth information on the complete extension architecture, best coding practices and learn how to distribute your chrome extension on the chrome web store.

Related Articles