Tạo trình quản lý thẻ đầu tiên.
Tổng quan
Hướng dẫn này sẽ tạo một trình quản lý thẻ để sắp xếp các thẻ tiện ích của Chrome và thẻ tài liệu của Cửa hàng Chrome trực tuyến.
Trong hướng dẫn này, chúng tôi sẽ giải thích cách thực hiện những thao tác sau:
- Tạo cửa sổ bật lên của tiện ích bằng API Action.
- Truy vấn các thẻ cụ thể bằng API Tabs.
- Bảo vệ quyền riêng tư của người dùng thông qua các quyền hạn chế đối với máy chủ lưu trữ.
- Thay đổi tiêu điểm của thẻ.
- Di chuyển các thẻ vào cùng một cửa sổ và nhóm chúng lại với nhau.
- Đổi tên nhóm thẻ bằng API TabGroups.
Trước khi bắt đầu
Hướng dẫn này giả định rằng bạn đã có kinh nghiệm cơ bản về phát triển web. Bạn nên xem Hello World để biết thông tin giới thiệu về quy trình phát triển tiện ích.
Tạo tiện ích
Để bắt đầu, hãy tạo một thư mục mới có tên tabs-manager để lưu trữ các tệp của tiện ích. Nếu muốn, bạn có thể tải mã nguồn hoàn chỉnh xuống trên GitHub.
Bước 1: Thêm dữ liệu và biểu tượng của tiện ích
Tạo một tệp có tên là manifest.json rồi thêm đoạn mã sau:
{
"manifest_version": 3,
"name": "Tab Manager for Chrome Dev Docs",
"version": "1.0",
"icons": {
"16": "images/icon-16.png",
"32": "images/icon-32.png",
"48": "images/icon-48.png",
"128": "images/icon-128.png"
}
}
Để tìm hiểu thêm về các khoá tệp kê khai này, hãy xem hướng dẫn về Thời gian đọc. Hướng dẫn này giải thích chi tiết hơn về siêu dữ liệu và biểu tượng của tiện ích.
Tạo thư mục images rồi tải các biểu tượng xuống thư mục đó.
Bước 2: Tạo và tạo kiểu cho cửa sổ bật lên
API Action kiểm soát thao tác của tiện ích (biểu tượng trên thanh công cụ). Khi người dùng nhấp vào thao tác trên tiện ích, thao tác này sẽ chạy một đoạn mã hoặc mở một cửa sổ bật lên, như trong trường hợp này. Bắt đầu bằng cách khai báo cửa sổ bật lên trong manifest.json:
{
"action": {
"default_popup": "popup.html"
}
}
Cửa sổ bật lên tương tự như một trang web, chỉ khác ở chỗ cửa sổ này không thể chạy JavaScript nội tuyến. Tạo tệp một popup.html rồi thêm đoạn mã sau:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="./popup.css" />
</head>
<body>
<template id="li_template">
<li>
<a>
<h3 class="title">Tab Title</h3>
<p class="pathname">Tab Pathname</p>
</a>
</li>
</template>
<h1>Google Dev Docs</h1>
<button>Group Tabs</button>
<ul></ul>
<script src="./popup.js" type="module"></script>
</body>
</html>
Tiếp theo, bạn sẽ tạo kiểu cho cửa sổ bật lên. Tạo tệp một popup.css rồi thêm đoạn mã sau:
body {
width: 20rem;
}
ul {
list-style-type: none;
padding-inline-start: 0;
margin: 1rem 0;
}
li {
padding: 0.25rem;
}
li:nth-child(odd) {
background: #80808030;
}
li:nth-child(even) {
background: #ffffff;
}
h3,
p {
margin: 0;
}
Bước 3: Quản lý các thẻ
Tabs API cho phép một tiện ích tạo, truy vấn, sửa đổi và sắp xếp lại các thẻ trong trình duyệt.
Yêu cầu cấp quyền
Bạn có thể sử dụng nhiều phương thức trong Tabs API mà không cần yêu cầu bất kỳ quyền nào. Tuy nhiên, chúng tôi cần có quyền truy cập vào title và URL của các thẻ; những thuộc tính nhạy cảm này yêu cầu có quyền. Chúng tôi có thể yêu cầu quyền "tabs", nhưng quyền này sẽ cho phép truy cập vào các thuộc tính nhạy cảm của tất cả các thẻ. Vì chỉ quản lý các thẻ của một trang web cụ thể, nên chúng ta sẽ yêu cầu quyền truy cập vào máy chủ lưu trữ có phạm vi hẹp.
Việc thu hẹp quyền truy cập của máy chủ lưu trữ cho phép chúng tôi bảo vệ quyền riêng tư của người dùng bằng cách cấp quyền nâng cao cho các trang web cụ thể. Thao tác này sẽ cấp quyền truy cập vào các thuộc tính title và URL, cũng như các chức năng bổ sung. Thêm đoạn mã được đánh dấu vào tệp manifest.json:
{
"host_permissions": [
"https://developer.chrome.com/*"
]
}
💡 Đâu là những điểm khác biệt chính giữa quyền đối với thẻ và quyền đối với máy chủ lưu trữ?
Cả quyền "tabs" và quyền truy cập vào máy chủ lưu trữ đều có nhược điểm.
Quyền "tabs" cho phép tiện ích đọc dữ liệu nhạy cảm trên tất cả các thẻ. Theo thời gian, thông tin này có thể được dùng để thu thập nhật ký duyệt web của người dùng. Do đó, nếu bạn yêu cầu quyền này, Chrome sẽ hiển thị thông báo cảnh báo sau đây tại thời điểm cài đặt:

Quyền từ phía máy chủ cho phép tiện ích đọc và truy vấn các thuộc tính nhạy cảm của thẻ khớp, đồng thời chèn tập lệnh vào các thẻ này. Người dùng sẽ thấy thông báo cảnh báo sau đây tại thời điểm cài đặt:

Những cảnh báo này có thể khiến người dùng lo ngại. Để có trải nghiệm làm quen tốt hơn, bạn nên triển khai các quyền không bắt buộc.
Truy vấn các thẻ
Bạn có thể truy xuất các thẻ từ các URL cụ thể bằng phương thức tabs.query(). Tạo tệp popup.js rồi thêm đoạn mã sau:
const tabs = await chrome.tabs.query({
url: [
"https://developer.chrome.com/docs/webstore/*",
"https://developer.chrome.com/docs/extensions/*",
]
});
💡 Tôi có thể sử dụng trực tiếp các API của Chrome trong cửa sổ bật lên không?
Cửa sổ bật lên và các trang tiện ích khác có thể gọi bất kỳ Chrome API nào vì chúng được phân phát từ lược đồ chrome. Ví dụ: chrome-extension://EXTENSION_ID/popup.html.
Tập trung vào một thẻ
Trước tiên, tiện ích này sẽ sắp xếp tên thẻ (tiêu đề của các trang HTML có trong thẻ) theo bảng chữ cái. Sau đó, khi người dùng nhấp vào một mục trong danh sách, mục đó sẽ tập trung vào thẻ đó bằng cách sử dụng tabs.update() và đưa cửa sổ lên trước bằng cách sử dụng windows.update().
Thêm đoạn mã sau đây vào tệp popup.js:
...
const collator = new Intl.Collator();
tabs.sort((a, b) => collator.compare(a.title, b.title));
const template = document.getElementById("li_template");
const elements = new Set();
for (const tab of tabs) {
const element = template.content.firstElementChild.cloneNode(true);
const title = tab.title.split("-")[0].trim();
const pathname = new URL(tab.url).pathname.slice("/docs".length);
element.querySelector(".title").textContent = title;
element.querySelector(".pathname").textContent = pathname;
element.querySelector("a").addEventListener("click", async () => {
// need to focus window as well as the active tab
await chrome.tabs.update(tab.id, { active: true });
await chrome.windows.update(tab.windowId, { focused: true });
});
elements.add(element);
}
document.querySelector("ul").append(...elements);
...
💡 JavaScript thú vị được dùng trong mã này
- Collator dùng để sắp xếp mảng thẻ theo ngôn ngữ ưu tiên của người dùng.
- Thẻ mẫu dùng để xác định một phần tử HTML có thể được sao chép thay vì dùng
document.createElement()để tạo từng mục. - Hàm khởi tạo URL dùng để tạo và phân tích cú pháp URL.
- Cú pháp trải rộng dùng để chuyển đổi Nhóm phần tử thành các đối số trong lệnh gọi
append().
Nhóm các thẻ
API TabGroups cho phép tiện ích đặt tên cho nhóm và chọn màu nền. Thêm quyền "tabGroups" vào tệp kê khai bằng cách thêm mã được đánh dấu:
{
"permissions": [
"tabGroups"
]
}
Trong popup.js, hãy thêm mã sau để tạo một nút sẽ nhóm tất cả các thẻ bằng tabs.group() và di chuyển các thẻ đó vào cửa sổ hiện tại.
const button = document.querySelector("button");
button.addEventListener("click", async () => {
const tabIds = tabs.map(({ id }) => id);
if (tabIds.length) {
const group = await chrome.tabs.group({ tabIds });
await chrome.tabGroups.update(group, { title: "DOCS" });
}
});
Kiểm tra để đảm bảo tính năng này hoạt động
Xác minh rằng cấu trúc tệp của dự án khớp với cây thư mục sau:

Tải tiện ích của bạn xuống cục bộ
Để tải một tiện ích đã giải nén ở chế độ nhà phát triển, hãy làm theo các bước trong phần Hello World.
Mở một vài trang tài liệu
Mở các tài liệu sau trong các cửa sổ khác nhau:
- Thiết kế giao diện người dùng
- Khám phá trên Cửa hàng Chrome trực tuyến
- Tổng quan về việc phát triển tiện ích
- Định dạng tệp kê khai
- Xuất bản trong Cửa hàng Chrome trực tuyến
Nhấp vào cửa sổ bật lên. Phần khai báo sẽ có dạng như sau:
Nhấp vào nút "Nhóm thẻ". Phần khai báo sẽ có dạng như sau:
🎯 Các điểm có thể cải thiện
Dựa trên những gì bạn đã học được hôm nay, hãy thử triển khai một trong những nội dung sau:
- Tuỳ chỉnh biểu định kiểu của cửa sổ bật lên.
- Thay đổi màu sắc và tiêu đề của nhóm thẻ.
- Quản lý các thẻ của một trang web tài liệu khác.
- Thêm tính năng hỗ trợ cho việc huỷ nhóm các thẻ được nhóm.
Hãy tiếp tục xây dựng!
Chúc mừng bạn đã hoàn thành hướng dẫn này 🎉. Hãy tiếp tục phát triển các kỹ năng của bạn bằng cách hoàn thành các hướng dẫn khác trong loạt hướng dẫn này:
| Phần mở rộng | Kiến thức bạn sẽ học được |
|---|---|
| Thời gian đọc | Cách tự động chèn một phần tử vào mọi trang. |
| Chế độ tập trung | Để chạy mã trên trang hiện tại sau khi nhấp vào thao tác của tiện ích. |
Tiếp tục khám phá
Chúng tôi hy vọng bạn thích thú khi tạo tiện ích của Chrome này và sẵn sàng tiếp tục hành trình học tập phát triển trên Chrome. Bạn nên tham khảo lộ trình học tập sau:
- Hướng dẫn dành cho nhà phát triển có hàng chục đường liên kết bổ sung đến các phần tài liệu liên quan đến việc tạo tiện ích nâng cao.
- Tiện ích có quyền truy cập vào các API mạnh mẽ ngoài những API có trên web mở. Tài liệu về Chrome API trình bày từng API.