• AFFHUB CONNECT WARSAW MEETUP: купуй квитки за посиланням
  • AFFHUB CONNECT WARSAW MEETUP: купуй квитки за посиланням
  • AFFHUB CONNECT WARSAW MEETUP: купуй квитки за посиланням
img
img
  • 5
  • 0
  • 0

Як створити власне розширення в Хром, яке прибирає сміття з сайту

Думаємо, майже у кожного виникала пасивна боротьба з сміттям на вебсайті, у якій користувач так і не здобував бажаної перемоги.

Як ви можете зрозуміти, мова йде про численні реклами на сацтах, які часто заважають переглядати матеріал, попапи тощо. Комусь на це байдуж, а для когось це суцільний жах. 

Що ж, дякуємо технологіям, які дозволяють розв’язати цю проблему й усунути незручності під час перегляду сайтів. У статті розбираємо, як створити розширення, яке прибирає сміття й дозволяє комфортно користуватися браузером.

Деталі шукайте нижче. Погнали розбиратися!

Трохи про конструкцію розширення

Наше розширення буде складатися з:

  • manifest.json — файл, який дасть зрозуміти браузеру, що це саме розширення.  
  • content.js — файл, де буде зосереджена основна логіка роботи розширення.
  • background.js — логіка роботи контекстного меню. 
  • popup.html — меню управління увімкненням та вимкненням розширення на веб сайтах.
  • popup.js — логіка попереднього меню.

Як створити це розширення?

Спершу потрібно створити папку з будь-якою назвою , а вже в ній створюємо 5 вище згаданих файлів (manifest.json, content.js, background.js, popup.html, popup.js). 

Далі такий алгоритм дій:

  1. Відкриваємо manifest.json і вставляємо в нього:

{

“manifest_version”:3,

“name”:”Element Cleaner Per Site”,

“version”:”2.0.0″,

“description”:”Видалення елементів сторінок через контекстне меню з увімкненням по окремих сайтах.”,

“permissions”:[

“contextMenus”,

“tabs”,

“storage”,

“activeTab”

],

“host_permissions”:[

“<all_urls>”

],

“background”:{

“service_worker”:”background.js”

},

“action”:{

“default_title”:”Element Cleaner”,

“default_popup”:”popup.html”

},

“content_scripts”:[

{

“matches”:[

“<all_urls>”

],

“js”:[

“content.js”

],

“run_at”:”document_start”

}

]

}

  1. Зберігаємо manifest.json
  2. Відкриваємо content.js і вставляємо в нього:

let selectedElement=null;

let hoverElement=null;

let extensionEnabled=false;

let lastOutline=””;

function checkState(){

chrome.storage.sync.get(

[“enabledSites”],

result=>{

const sites=

Array.isArray(result.enabledSites)

? result.enabledSites

: [];

extensionEnabled=

sites.includes(location.hostname);

if(!extensionEnabled){

removeHighlight();

}

}

);

}

function applyHighlight(element){

if(!element) return;

if(hoverElement===element){

return;

}

removeHighlight();

hoverElement=element;

lastOutline=

element.style.outline;

element.style.outline=

“3px solid red”;

element.style.outlineOffset=

“2px”;

}

function removeHighlight(){

if(hoverElement){

hoverElement.style.outline=

lastOutline || “”;

hoverElement.style.outlineOffset=””;

}

hoverElement=null;

lastOutline=””;

}

document.addEventListener(

“mousemove”,

event=>{

if(!extensionEnabled){

return;

}

const element=

event.target;

if(

element &&

element!==document.body &&

element!==document.documentElement

){

applyHighlight(element);

}

},

true

);

document.addEventListener(

“mouseleave”,

()=>{

removeHighlight();

},

true

);

document.addEventListener(

“contextmenu”,

event=>{

if(!extensionEnabled){

return;

}

selectedElement=

event.target;

applyHighlight(selectedElement);

},

true

);

chrome.storage.onChanged.addListener(()=>{

checkState();

});

chrome.runtime.onMessage.addListener(

message=>{

if(message.action===”remove_element”){

if(

extensionEnabled &&

selectedElement

){

selectedElement.remove();

selectedElement=null;

}

}

if(message.action===”remove_parent_element”){

if(

extensionEnabled &&

selectedElement

){

const parent=

selectedElement.parentElement;

if(parent){

parent.remove();

}

selectedElement=null;

}

}

}

);

checkState();

  1. Зберігаємо content.js
  2. Відкриваємо background.js і вставляємо:

const REMOVE_MENU_ID=”remove_element”;

const REMOVE_PARENT_MENU_ID=”remove_parent_element”;

function getHostname(url){

try{

return new URL(url).hostname;

}catch(e){

return “”;

}

}

function getEnabledSites(){

return new Promise(resolve=>{

chrome.storage.sync.get(

[“enabledSites”],

result=>{

resolve(

Array.isArray(result.enabledSites)

? result.enabledSites

: []

);

}

);

});

}

async function isEnabledForTab(tab){

if(!tab || !tab.url){

return false;

}

const hostname=getHostname(tab.url);

const sites=await getEnabledSites();

return sites.includes(hostname);

}

function createContextMenu(){

chrome.contextMenus.removeAll(()=>{

chrome.contextMenus.create({

id:REMOVE_MENU_ID,

title:”Видалити елемент”,

contexts:[“all”]

});

chrome.contextMenus.create({

id:REMOVE_PARENT_MENU_ID,

title:”Видалити батьківський елемент”,

contexts:[“all”]

});

});

}

async function refreshMenu(tabId,url){

const enabled=

(await getEnabledSites())

.includes(getHostname(url));

if(enabled){

createContextMenu();

}else{

chrome.contextMenus.removeAll();

}

}

chrome.runtime.onInstalled.addListener(()=>{

chrome.contextMenus.removeAll();

});

chrome.storage.onChanged.addListener(()=>{

chrome.tabs.query(

{},

tabs=>{

tabs.forEach(tab=>{

if(tab.url){

refreshMenu(

tab.id,

tab.url

);

}

});

}

);

});

chrome.tabs.onActivated.addListener(info=>{

chrome.tabs.get(

info.tabId,

tab=>{

if(tab && tab.url){

refreshMenu(

tab.id,

tab.url

);

}

}

);

});

chrome.tabs.onUpdated.addListener(

(tabId,changeInfo,tab)=>{

if(changeInfo.url){

refreshMenu(

tabId,

changeInfo.url

);

}

}

);

chrome.contextMenus.onClicked.addListener(

async(info,tab)=>{

if(!await isEnabledForTab(tab)){

return;

}

chrome.tabs.sendMessage(

tab.id,

{

action:info.menuItemId

}

);

}

);

  1. Зберігаємо background.js
  2. Відкриваємо popup.html і вставляємо:

<!DOCTYPE html>

<html lang=”ru”>

<head>

<meta charset=”UTF-8″>

<title>Element Cleaner</title>

<style>

body{

width:350px;

padding:14px;

margin:0;

font-family:Arial,sans-serif;

background:#f7f7f7;

color:#222;

}

h2{

margin:0 0 12px 0;

font-size:20px;

}

.description{

font-size:12px;

opacity:.75;

line-height:1.4;

margin-bottom:12px;

}

.panel{

background:white;

border:1px solid #d5d5d5;

padding:10px;

margin-bottom:12px;

}

.caption{

font-size:12px;

opacity:.7;

}

.current-site{

margin-top:6px;

font-weight:bold;

word-break:break-all;

}

.status{

margin-top:8px;

padding:6px;

text-align:center;

border:1px solid #ddd;

font-size:12px;

}

button{

width:100%;

padding:8px;

margin-top:8px;

cursor:pointer;

}

.sites-title{

margin-bottom:8px;

}

.sites-list{

max-height:170px;

overflow-y:auto;

border:1px solid #ddd;

background:#fff;

}

.site-row{

display:flex;

justify-content:space-between;

align-items:center;

padding:6px;

border-bottom:1px solid #eee;

font-size:12px;

}

.site-name{

overflow:hidden;

text-overflow:ellipsis;

}

.delete-button{

width:auto;

margin:0;

padding:3px 8px;

}

.empty{

padding:8px;

opacity:.6;

font-size:12px;

}

.footer{

margin-top:10px;

text-align:center;

font-size:11px;

opacity:.5;

}

</style>

</head>

<body>

<h2>

Element Cleaner

</h2>

<div class=”description”>

Розширення повністю вмикається тільки на обраних сайтах.

На інших сторінках воно не додає пункти у контекстне меню.

</div>

<div class=”panel”>

<div class=”caption”>

Поточний сайт:

</div>

<div

id=”currentSite”

class=”current-site”

>

Визначення…

</div>

<div

id=”status”

class=”status”

>

Перевірка стану…

</div>

<button

id=”toggleButton”

>

Завантаження…

</button>

</div>

<div class=”panel”>

<div class=”sites-title”>

Активні сайти:

</div>

<div

id=”sitesList”

class=”sites-list”

>

</div>

<button

id=”addButton”

>

Додати поточний сайт

</button>

</div>

<div class=”footer”>

Element Cleaner • Site control

</div>

<script src=”popup.js”></script>

</body>

</html>

  1. Зберігаємо popup.html
  2. Відкриваємо popup.js і вставляємо:

const currentSiteElement =

document.getElementById(“currentSite”);

const statusElement =

document.getElementById(“status”);

const toggleButton =

document.getElementById(“toggleButton”);

const addButton =

document.getElementById(“addButton”);

const sitesListElement =

document.getElementById(“sitesList”);

let currentHostname=””;

let enabledSites=[];

function getCurrentTab(){

return new Promise(resolve=>{

chrome.tabs.query(

{

active:true,

currentWindow:true

},

tabs=>{

if(tabs && tabs[0]){

resolve(tabs[0]);

}else{

resolve(null);

}

}

);

});

}

function extractHostname(url){

try{

return new URL(url).hostname;

}catch(error){

return “”;

}

}

function loadEnabledSites(){

return new Promise(resolve=>{

chrome.storage.sync.get(

[“enabledSites”],

result=>{

if(

result &&

Array.isArray(result.enabledSites)

){

resolve(

result.enabledSites

);

}else{

resolve([]);

}

}

);

});

}

function saveEnabledSites(list){

return new Promise(resolve=>{

chrome.storage.sync.set(

{

enabledSites:list

},

()=>{

resolve();

}

);

});

}

function isEnabled(site){

return enabledSites.includes(site);

}

function updateStatus(){

if(isEnabled(currentHostname)){

statusElement.textContent=

“Розширення активне на цьому сайті”;

toggleButton.textContent=

“Вимкнути розширення на сайті”;

}else{

statusElement.textContent=

“Розширення вимкнене на цьому сайті”;

toggleButton.textContent=

“Увімкнути розширення на сайті”;

}

}

function renderCurrentSite(){

currentSiteElement.textContent=

currentHostname || “Не найден”;

updateStatus();

}

function renderSites(){

sitesListElement.innerHTML=””;

if(enabledSites.length===0){

const empty=

document.createElement(“div”);

empty.className=”empty”;

empty.textContent=

“Немає активних сайтів”;

sitesListElement.appendChild(empty);

return;

}

enabledSites.forEach(site=>{

const row=

document.createElement(“div”);

row.className=

“site-row”;

const name=

document.createElement(“div”);

name.className=

“site-name”;

name.textContent=

site;

const button=

document.createElement(“button”);

button.className=

“delete-button”;

button.textContent=

“Видалити”;

button.onclick=

async()=>{

enabledSites=

enabledSites.filter(

item=>

item!==site

);

await saveEnabledSites(

enabledSites

);

renderSites();

renderCurrentSite();

};

row.appendChild(name);

row.appendChild(button);

sitesListElement.appendChild(row);

});

}

async function toggleSite(){

if(!currentHostname){

return;

}

if(isEnabled(currentHostname)){

enabledSites=

enabledSites.filter(

item=>

item!==currentHostname

);

}else{

enabledSites.push(

currentHostname

);

}

await saveEnabledSites(

enabledSites

);

renderSites();

renderCurrentSite();

}

async function addCurrentSite(){

if(!currentHostname){

return;

}

if(!isEnabled(currentHostname)){

enabledSites.push(

currentHostname

);

await saveEnabledSites(

enabledSites

);

}

renderSites();

renderCurrentSite();

}

function bindEvents(){

toggleButton.onclick=

toggleSite;

addButton.onclick=

addCurrentSite;

}

async function init(){

const tab=

await getCurrentTab();

if(!tab){

return;

}

currentHostname=

extractHostname(tab.url);

enabledSites=

await loadEnabledSites();

renderCurrentSite();

renderSites();

bindEvents();

}

document.addEventListener(

“DOMContentLoaded”,

init

);

  1. Зберігаємо popup.js

Як почати використання розширення?

Тут все просто:

  • Відкрийте Chrome і натисніть на «три крапки». 
  • Далі на «Розширення», 
  • Наступний крок – «Управління розширеннями”
  • І нарешті – «Завантажити розпаковане розширення». Тут нашу папку і обираємо її. Перевірте, чи ви увімкнули розширення для конкретного сайту і все – насолоджуйтеся!

Замість висновків

Здавалося, дрібниця, а приємно ж.

Навіщо терпіти банери на увесь екран, через які ледь проглядається вміст сайту, якщо можна за пів години спростити собі життя й зробити використання браузера більш комфортним.

Тож, друзі, пробуйте, користуйтеся – бажаємо вам більше браузерного комфорту!

  • 5
  • 0
  • 0
18.09.2026
Зареєструйся, щоб залишити коментар
0
  • За рейтингом
  • По порядку
loading