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ẻ tài liệu về tiện ích Chrome và 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 việ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 (Thẻ).
- Bảo vệ quyền riêng tư của người dùng thông qua các quyền hạn chế của máy chủ lưu trữ.
- Thay đổi tiêu điểm của thẻ.
- Di chuyển các thẻ sang cùng một cửa sổ và nhóm các thẻ đó 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 phát triển web cơ bản. Bạn nên xem bài viết Xin chào thế giới để tìm hiể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 đầy đủ xuống trên GitHub.
Bước 1: Thêm dữ liệu và biểu tượng tiện ích
Tạo một tệp có tên là manifest.json
và thêm 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 biểu tượng xuống vào thư mục đó.
Bước 2: Tạo và tạo kiểu cho cửa sổ bật lên
API Action (Hành động) kiểm soát hành động của tiện ích (biểu tượng thanh công cụ). Khi người dùng nhấp vào thao tác của tiện ích, thao tác đó sẽ chạy một số 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, ngoại trừ một điểm: cửa sổ này không thể chạy JavaScript cùng dòng. 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 quyền. Tuy nhiên, chúng ta cần quyền truy cập vào title
và URL
của các thẻ; các thuộc tính nhạy cảm này yêu cầu quyền. Chúng ta có thể yêu cầu quyền "tabs"
, nhưng điều này sẽ cấp quyền truy cập vào các thuộc tính nhạy cảm của tất 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 cấp quyền hẹp cho máy chủ lưu trữ.
Việc thu hẹp quyền 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 mã được làm nổi bật 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 của máy chủ đều có những hạn chế.
Quyền "tabs"
cấp cho tiện ích khả năng đọ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ẻ trùng 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ể gây lo ngại cho người dùng. Để mang lại 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 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 API Chrome trực tiếp trong cửa sổ bật lên không?
Một cửa sổ bật lên và các trang tiện ích khác có thể gọi bất kỳ API Chrome nào vì các trang này được phân phát từ
giản đồ chrome. Ví dụ: chrome-extension://EXTENSION_ID/popup.html
.
Đặt tiêu điểm 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 đó) theo thứ tự 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 tabs.update()
và đưa cửa sổ lên trước bằng windows.update()
.
Thêm mã sau 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ì sử 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 truyền dữ liệu dùng để chuyển đổi Tập hợp các phần tử thành đố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 làm nổi bật:
{
"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à 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 thử để đả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 trên máy
Để tải một tiện ích chưa 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 trên Cửa hàng Chrome trực tuyến
Nhấp vào cửa sổ bật lên. Ứng dụng sẽ hiển thị như sau:
Nhấp vào nút "Nhóm thẻ". Ứng dụng sẽ hiển thị như sau:
🎯 Các điểm cải tiến tiềm năng
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 cách sau:
- Tuỳ chỉnh trang tính kiểu của cửa sổ bật lên.
- Thay đổi màu 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ợ để huỷ nhóm các thẻ đã 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 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 bài viết này:
Phần mở rộng | Kiến thức bạn sẽ học được |
---|---|
Thời gian đọc | Để tự động chèn một phần tử trên mọi trang. |
Chế độ lấy nét | Để chạy mã trên trang hiện tại sau khi nhấp vào hành động của tiện ích. |
Tiếp tục khám phá
Chúng tôi hy vọng bạn đã có trải nghiệm thú vị khi xây dựng tiện ích Chrome này và rất mong được tiếp tục hành trình tìm hiểu về việc phát triển Chrome cùng bạn. 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 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ề API Chrome trình bày từng API.