Trong bài viết này, chúng ta sẽ tìm hiểu về tiện ích mở rộng trình duyệt (browser extensions) – chúng là gì, hoạt động như thế nào, và cách bạn có thể tự xây dựng một tiện ích riêng.
Chúng ta sẽ kết thúc bằng việc viết một tiện ích thực tế (Rất thú vị!) cho phép sao chép bất kỳ đoạn mã nào vào clipboard chỉ với một cú nhấp chuột.
Để theo dõi bài viết này:
- Bạn cần có kiến thức cơ bản về JavaScript.
- Bạn cần trình duyệt Firefox (hoặc bất kỳ trình duyệt nào khác cũng hoạt động).
Tiện Ích Mở Rộng Trình Duyệt Là Gì?
Tiện ích mở rộng trình duyệt là một thành phần bạn thêm vào trình duyệt để nâng cao trải nghiệm duyệt web bằng cách mở rộng khả năng của trình duyệt.
Ví dụ điển hình là trình chặn quảng cáo (ad blocker) mà bạn có thể đã cài đặt. Nó cải thiện trải nghiệm duyệt web bằng cách chặn quảng cáo khi bạn lướt mạng.
Cách Viết Tiện Ích Mở Rộng Cơ Bản
Bây giờ, hãy bắt đầu viết một tiện ích rất cơ bản.
Trước tiên, tạo một thư mục và bên trong tạo file tên manifest.json.
File Manifest Là Gì?
File manifest là file bắt buộc trong mọi tiện ích mở rộng trình duyệt. File này chứa thông tin cơ bản về tiện ích như tên, phiên bản, v.v.
Sao chép đoạn mã sau vào file manifest.json:
{ "manifest_version": 2, "version": "1.0", "name": "Test" }Cách Tải File Tiện Ích
Đối với người dùng Firefox, làm theo các bước sau:
Trong thanh địa chỉ, tìm kiếm:
about:debugging#/runtime/this-firefoxBạn sẽ thấy tùy chọn Load Temporary Add-on. Nhấp vào đó và chọn file manifest.json từ thư mục.
Đối với người dùng Chrome:
Trong thanh địa chỉ tìm kiếm:
chrome://extensions- Bật Developer Mode (Chế độ nhà phát triển).
- Nhấp nút Load unpacked và chọn thư mục tiện ích.
Chúc mừng! Bạn đã cài đặt tiện ích thành công. Nhưng tiện ích chưa làm gì cả. Hãy thêm chức năng bằng cách chỉnh sửa manifest.json như sau:
{ "manifest_version": 2, "version": "1.0", "name": "Test", "content_scripts": [ { "matches": [""], "js": ["main.js"] } ] } Ở trên, chúng ta thêm content script vào manifest.json. Content script có thao tác được với Document Object Model (DOM) của trang web. Chúng ta có thể chèn JS (và CSS) vào trang web bằng content script.
"matches" chứa danh sách domain và subdomain nơi content script sẽ được thêm, js là mảng các file JS cần tải.
Tạo file main.js trong cùng thư mục và thêm mã:
alert("Tiện ích test đang hoạt động")Tải lại tiện ích và truy cập bất kỳ URL nào, bạn sẽ thấy thông báo alert.
Lưu ý: Đừng quên tải lại tiện ích mỗi khi chỉnh sửa mã.
Cách Tùy Chỉnh Tiện Ích Mở Rộng
Hãy thêm chút vui vẻ hơn cho tiện ích.
Chúng ta sẽ tạo tiện ích thay đổi tất cả hình ảnh trên trang web thành hình ảnh do chúng ta chọn.
Thêm một hình ảnh bất kỳ vào thư mục hiện tại và sửa file main.js:
console.log("Tiện ích đang hoạt động"); var images = document.getElementsByTagName('img'); for (elt of images) { elt.src = `${browser.runtime.getURL("pp.jpg")}`; elt.alt = 'văn bản thay thế'; }Giải thích:
var images = document.getElementsByTagName('img')Dòng này chọn tất cả phần tử có thẻ img trên trang.
Sau đó lặp qua mảng images, thay đổi thuộc tính src của tất cả phần tử img thành URL nhờ hàm runtime.getURL.
pp.jpg là tên file hình ảnh trong thư mục hiện tại.
Cần khai báo file pp.jpg cho content script bằng cách sửa manifest.json:
{ "manifest_version": 2, "version": "1.0", "name": "Test", "content_scripts": [ { "matches": [""], "js": ["main.js"] } ], "web_accessible_resources": [ "pp.jpg" ] } Tải lại tiện ích và truy cập bất kỳ URL nào. Tất cả hình ảnh sẽ thay đổi thành hình ảnh trong thư mục của bạn.
Cách Thêm Biểu Tượng Cho Tiện Ích
Thêm mã sau vào manifest.json:
"icons": { "48": "icon-48.png", "96": "icon-96.png" }Cách Thêm Nút Thanh Công Cụ
Thêm nút trên thanh công cụ trình duyệt để người dùng tương tác với tiện ích.
Thêm vào manifest.json:
"browser_action": { "default_icon": { "19": "icon-19.png", "38": "icon-38.png" } }Tất cả file hình ảnh phải có trong thư mục hiện tại.
Tải lại tiện ích, bạn sẽ thấy biểu tượng tiện ích trên thanh công cụ.
Cách Thêm Sự Kiện Lắng Cho Nút Thanh Công Cụ
Giả sử muốn mở tab mới khi nhấp nút.
Thêm vào manifest.json:
"background": { "scripts": ["background.js"] }, "permissions": [ "tabs" ]Tạo file background.js và thêm:
function openTab() { var newTab = browser.tabs.create({ url: 'https://twitter.com/abhilekh_gautam', active: true }); } browser.browserAction.onClicked.addListener(openTab);Tải lại tiện ích!
Khi nhấp nút, hàm openTab mở tab mới với URL hồ sơ Twitter. Khóa active: true làm tab mới thành tab hiện tại.
Lưu ý: Bạn có thể dùng API trình duyệt trong background script. Xem thêm tại: JavaScript APIs.
Sau khi nắm cơ bản, hãy tạo tiện ích hữu ích cho lập trình viên.
Dự Án Cuối Khóa
Chúng ta sẽ viết tiện ích cho phép sao chép đoạn mã từ StackOverflow chỉ với một cú nhấp. Tiện ích sẽ thêm nút Copy vào trang để sao chép mã vào clipboard.
Demo

Tạo thư mục mới, thêm file manifest.json:
{ "manifest_version": 2, "version": "1.0", "name": "copy code", "content_scripts": [ { "matches": ["*://*.stackoverflow.com/*"], "js": ["main.js"] } ] }Chú ý matches trong content script – tiện ích chỉ hoạt động trên domain và subdomain của StackOverflow.
Tạo file main.js và thêm mã:
var arr = document.getElementsByClassName("s-code-block"); for (let i = 0; i < arr.length; i++) { var btn = document.createElement("button"); btn.classList.add("copy_code_button"); btn.appendChild(document.createTextNode("Copy")); arr[i].appendChild(btn); // Tạo kiểu cho nút btn.style.position = "relative"; if (arr[i].scrollWidth === arr[i].offsetWidth && arr[i].scrollHeight === arr[i].offsetHeight) btn.style.left = `${arr[i].offsetWidth - 70}px`; else if (arr[i].scrollWidth != arr[i].offsetWidth && arr[i].scrollHeight === arr[i].offsetWidth) btn.style.left = `${arr[i].offsetWidth - 200}px`; else btn.style.left = `${arr[i].offsetWidth - 150}px`; if (arr[i].scrollHeight === arr[i].offsetHeight) btn.style.bottom = `${arr[i].offsetHeight - 50}px`; else btn.style.bottom = `${arr[i].scrollHeight - 50}px`; // Kết thúc tạo kiểu console.log("Đã thêm"); }Trước tiên, chọn tất cả phần tử có class s-code-block – vì khi kiểm tra trang StackOverflow, tất cả đoạn mã đều nằm trong class này.
Sau đó lặp qua các phần tử và thêm nút. Cuối cùng, định vị và tạo kiểu cho nút (chưa hoàn hảo – chỉ là bước đầu).
Khi tải tiện ích và truy cập StackOverflow, bạn sẽ thấy nút Copy.
Cách Thêm Chức Năng Cho Nút
Khi nhấp nút, muốn sao chép toàn bộ đoạn mã vào clipboard. Thêm mã sau vào main.js:
var button = document.querySelectorAll(".copy_code_button"); button.forEach((elm) => { elm.addEventListener('click', (e) => { navigator.clipboard.writeText(elm.parentNode.childNodes[0].innerText); alert("Đã sao chép vào Clipboard"); }); });Chọn tất cả nút đã thêm bằng querySelectorAll. Lắng nghe sự kiện click.
navigator.clipboard.writeText(elm.parentNode.childNodes[0].innerText)Dòng này sao chép mã vào clipboard. Khi sao chép, thông báo Copied to clipboard hiện ra.
Kết Luận
Tiện ích mở rộng web hữu ích theo nhiều cách. Hy vọng bài viết giúp bạn tự viết tiện ích riêng.
Mã nguồn tại repository GitHub. Đừng ngần ngại gửi pull request khi có cải tiến giao diện hoặc tính năng mới như lịch sử clipboard.
Chúc bạn lập trình vui vẻ!