Vài năm trước, bốn API JavaScript đã nằm ở cuối danh sách nhận thức trong cuộc khảo sát State of JavaScript. Tôi quan tâm đến các API đó vì chúng có rất nhiều tiềm năng hữu ích nhưng không được ghi nhận xứng đáng. Ngay cả sau khi tìm kiếm nhanh, tôi vẫn ngạc nhiên về số lượng API web mới được thêm vào thông số kỹ thuật ECMAScript không nhận được sự công nhận xứng đáng và thiếu sự nhận thức cũng như hỗ trợ trình duyệt trong các trình duyệt.
Tình huống đó có thể là "catch-22":
Bạn có thể xem tất cả các API này đang hoạt động trong bản demo này khi chúng ta thực hiện.
Sử dụng đối tượng toàn cục
Đối tượng

Đây có thể là mẫu HTML của chúng ta:
Về phía JavaScript, chúng tôi đưa các thuộc tính
Bây giờ, chúng ta có thể thấy các thuộc tính hướng và góc của thiết bị. Trên máy tính xách tay của tôi, chúng là

Nếu chúng ta lắng nghe sự kiện

Để khóa màn hình, trước tiên chúng ta cần ở chế độ toàn màn hình, vì vậy chúng ta sẽ sử dụng một tính năng cực kỳ hữu ích khác: API toàn màn hình. Không ai muốn một trang web chuyển sang chế độ toàn màn hình mà không có sự đồng ý của họ, vì vậy chúng ta cần kích hoạt tạm thời (tức là người dùng nhấp chuột) từ một phần tử DOM để hoạt động.
API toàn màn hình có hai phương thức:
Tiếp theo, chúng ta có thể khóa màn hình theo hướng hiện tại:
Và làm ngược lại với nút mở khóa:

Xem Bút [Xoay khối [phân nhánh]](https://codepen.io/smashingmag/pen/vYwdMNJ) của Dave DeSandro.
Xem Bút Xoay khối [forked] của Dave DeSandro.
Bạn có thể thấy HTML thô đầy đủ trong bản demo, nhưng chúng ta hãy in nó ở đây để lưu giữ:
Để tóm tắt, tôi sẽ không giải thích mã CSS ở đây. Chỉ cần nhớ rằng mã này cung cấp các kiểu cần thiết cho khối lập phương 3D và có thể xoay qua tất cả các trục bằng hàm CSS
Bây giờ, với JavaScript, chúng ta lắng nghe sự kiện
Để xem dữ liệu thay đổi như thế nào trên thiết bị máy tính để bàn, chúng ta có thể mở DevTools của Chrome và truy cập Bảng điều khiển cảm biến để mô phỏng thiết bị xoay.

Để xoay khối lập phương, chúng ta thay đổi thuộc tính
Đây là kết quả:

Chỉ có một phương thức mà Vibration API cung cấp cho chúng ta và đó là tất cả những gì chúng ta cần:

Chúng ta sẽ thêm một trình lắng nghe sự kiện cho một cú nhấp và gọi phương thức
Để dừng rung, chúng tôi ghi đè rung hiện tại bằng rung không mili giây.
API này cấp cho các ứng dụng web quyền truy cập vào danh sách liên lạc của thiết bị. Cụ thể, chúng ta có phương thức async

Sau đó, trong JavaScript, trước tiên chúng ta xây dựng các phần tử của mình từ DOM và chọn các thuộc tính mà chúng ta muốn chọn từ các liên hệ.
Bây giờ, chúng ta chọn các liên hệ một cách không đồng bộ khi người dùng nhấp vào
Bằng cách sử dụng thao tác DOM, sau đó chúng ta có thể thêm một mục danh sách vào mỗi liên hệ và một biểu tượng vào phần tử
Việc thêm một hình ảnh hơi khó vì chúng ta sẽ cần chuyển đổi nó thành một URL và thêm nó cho từng mục trong danh sách.
Và đây là kết quả:

Lưu ý: API Contact Picker sẽ chỉ hoạt động nếu ngữ cảnh an toàn, tức là trang được phục vụ qua
Chúng không thú vị sao? Chúng ta đã thấy mức độ kiểm soát của chúng ta đối với hướng của thiết bị và màn hình của thiết bị cũng như mức độ truy cập mà chúng ta có thể truy cập vào các tính năng phần cứng của thiết bị, tức là độ rung và thông tin từ các ứng dụng khác để sử dụng trong giao diện người dùng của riêng chúng ta.
Nhưng như tôi đã nói trước đó, có một loại vòng lặp vô hạn trong đó thiếu nhận thức dẫn đến thiếu hỗ trợ trình duyệt. Vì vậy, mặc dù bốn API mà chúng tôi đã đề cập rất thú vị, nhưng kết quả của bạn chắc chắn sẽ khác khi sử dụng chúng trong môi trường sản xuất. Vui lòng thận trọng và tham khảo Caniuse để biết thông tin hỗ trợ mới nhất hoặc kiểm tra thiết bị của riêng bạn bằng WebAPI Check.
Tình huống đó có thể là "catch-22":
Hầu hết các API này được thiết kế để hỗ trợ các ứng dụng web tiến bộ (PWA) và thu hẹp khoảng cách giữa ứng dụng web và ứng dụng gốc. Hãy nhớ rằng việc tạo PWA không chỉ đơn thuần là thêm tệp kê khai. Chắc chắn, theo định nghĩa, đây là PWA, nhưng trên thực tế, nó hoạt động giống như một dấu trang trên màn hình chính của bạn. Trên thực tế, chúng ta cần một số API để đạt được trải nghiệm ứng dụng hoàn toàn gốc trên web. Và bốn API mà tôi muốn làm sáng tỏ là một phần của câu đố PWA mang đến cho web những gì chúng ta từng nghĩ chỉ có thể có trong các ứng dụng gốc.
Bạn có thể xem tất cả các API này đang hoạt động trong bản demo này khi chúng ta thực hiện.
1. API định hướng màn hình
Có thể sử dụng API định hướng màn hình để phát hiện hướng hiện tại của thiết bị. Khi biết được người dùng đang duyệt theo hướng dọc hay ngang, chúng ta có thể sử dụng nó để nâng cao UX cho thiết bị di động bằng cách thay đổi UI cho phù hợp. Chúng ta cũng có thể sử dụng nó để khóa màn hình ở một vị trí nhất định, điều này hữu ích khi hiển thị video và các thành phần toàn màn hình khác được hưởng lợi từ chế độ xem rộng hơn.Sử dụng đối tượng toàn cục
screen
, bạn có thể truy cập nhiều thuộc tính khác nhau mà màn hình sử dụng để hiển thị trang, bao gồm đối tượng screen.orientation
. Đối tượng này có hai thuộc tính:-
type
: Hướng màn hình hiện tại. Có thể là:"portrait-primary"
,"portrait-secondary"
,"landscape-primary"
hoặc"landscape-secondary"
. -
angle
: Góc hướng màn hình hiện tại. Có thể là bất kỳ số nào từ 0 đến 360 độ, nhưng thông thường được đặt theo bội số của 90 độ (ví dụ:0
,90
,180
hoặc270
).
góc
là 0
độ, thì kiểu
thường sẽ được đánh giá là "portrait"
(dọc), nhưng trên thiết bị máy tính để bàn, thông thường là "landscape"
(ngang). Điều này làm cho thuộc tính type
chính xác để biết vị trí thực của thiết bị.Đối tượng
screen.orientation
cũng có hai phương thức:-
.lock()
: Đây là phương thức bất đồng bộ lấy giá trịtype
làm đối số để khóa màn hình. -
.unlock()
: Phương thức này mở khóa màn hình về hướng mặc định của nó.
screen.orientation
đếm với sự kiện "orientationchange"
để biết khi nào hướng đã thay đổi.Hỗ trợ trình duyệt

Tìm và khóa hướng màn hình
Chúng ta hãy viết một bản demo ngắn bằng cách sử dụng API hướng màn hình để biết hướng của thiết bị và khóa thiết bị ở vị trí hiện tại.Đây có thể là mẫu HTML của chúng ta:
Mã:
Kiểu định hướng:
Góc định hướng:
Màn hình khóa Mở khóa màn hình Chuyển sang chế độ toàn màn hình
type
và angle
hướng màn hình vào HTML của chúng tôi.
Mã:
let currentOrientationType = document.querySelector(".orientation-type");let currentOrientationAngle = document.querySelector(".orientation-angle");currentOrientationType.textContent = screen.orientation.type;currentOrientationAngle.textContent = screen.orientation.angle;
"landscape-primary"
và 0°
.
Nếu chúng ta lắng nghe sự kiện
orientationchange
của cửa sổ, chúng ta có thể thấy các giá trị được cập nhật như thế nào mỗi khi màn hình xoay.
Mã:
window.addEventListener("orientationchange", () => { currentOrientationType.textContent = screen.orientation.type; currentOrientationAngle.textContent = screen.orientation.angle;});

Để khóa màn hình, trước tiên chúng ta cần ở chế độ toàn màn hình, vì vậy chúng ta sẽ sử dụng một tính năng cực kỳ hữu ích khác: API toàn màn hình. Không ai muốn một trang web chuyển sang chế độ toàn màn hình mà không có sự đồng ý của họ, vì vậy chúng ta cần kích hoạt tạm thời (tức là người dùng nhấp chuột) từ một phần tử DOM để hoạt động.
API toàn màn hình có hai phương thức:
-
Document.exitFullscreen()
được sử dụng từ đối tượng tài liệu toàn cục, -
Element.requestFullscreen()
làm cho phần tử được chỉ định và các phần tử con của nó chuyển sang chế độ toàn màn hình.
document.documentElement
:
Mã:
const fullscreenButton = document.querySelector(".fullscreen-button");fullscreenButton.addEventListener("click", async () => { // Nếu đã ở chế độ toàn màn hình, thoát về chế độ xem bình thường if (document.fullscreenElement) { await document.exitFullscreen(); } else { await document.documentElement.requestFullscreen(); }});
Mã:
const lockButton = document.querySelector(".lock-button");lockButton.addEventListener("click", async () => { try { await screen.orientation.lock(screen.orientation.type); } catch (error) { console.error(error); }});
Mã:
const unlockButton = document.querySelector(".unlock-button");unlockButton.addEventListener("click", () => { screen.orientation.unlock();});
Chúng ta không thể kiểm tra hướng bằng Media Query sao?
Có! Chúng ta thực sự có thể kiểm tra hướng trang thông qua tính năngorientation
media trong một truy vấn phương tiện CSS. Tuy nhiên, các truy vấn phương tiện tính toán hướng hiện tại bằng cách kiểm tra xem chiều rộng có "lớn hơn chiều cao" đối với chế độ ngang hay "nhỏ hơn" đối với chế độ dọc không. Ngược lại,Bạn có thể đã nhận thấy cách các PWA như Instagram và X buộc màn hình ở chế độ dọc ngay cả khi hướng hệ thống gốc được mở khóa. Điều quan trọng cần lưu ý là hành vi này không đạt được thông qua Screen Orientation API, mà bằng cách đặt thuộc tính
orientation
trên tệp manifest.json
thành loại hướng mong muốn.2. Device Orientation API
Một API khác mà tôi muốn đề cập đến là Device Orientation API. API này cung cấp quyền truy cập vào cảm biến con quay hồi chuyển của thiết bị để đọc hướng của thiết bị trong không gian; một tính năng luôn được sử dụng trong các ứng dụng di động, chủ yếu là trò chơi. API thực hiện điều này bằng sự kiệndeviceorientation
kích hoạt mỗi khi thiết bị di chuyển. Sự kiện này có các thuộc tính sau:-
event.alpha
: Định hướng theo trục Z, từ 0 đến 360 độ. -
event.beta
: Định hướng theo trục X, từ -180 đến 180 độ. -
event.gamma
: Định hướng theo trục Y, từ -90 đến 90 độ.
Hỗ trợ trình duyệt

Di chuyển các thành phần bằng thiết bị của bạn
Trong trường hợp này, chúng ta sẽ tạo một khối lập phương 3D bằng CSS có thể xoay bằng thiết bị của bạn! Hướng dẫn đầy đủ mà tôi sử dụng để tạo khối CSS ban đầu được ghi nhận là của David DeSandro và có thể được tìm thấy trong phần giới thiệu về phép biến đổi 3D của ông ấy.Xem Bút [Xoay khối [phân nhánh]](https://codepen.io/smashingmag/pen/vYwdMNJ) của Dave DeSandro.
Xem Bút Xoay khối [forked] của Dave DeSandro.
Bạn có thể thấy HTML thô đầy đủ trong bản demo, nhưng chúng ta hãy in nó ở đây để lưu giữ:
Mã:
1 2 3 4 5 6 [HEADING=1]API định hướng thiết bị[/HEADING]
Alpha:
Beta:
Gamma:
rotate()
.Bây giờ, với JavaScript, chúng ta lắng nghe sự kiện
deviceorientation
của cửa sổ và truy cập dữ liệu hướng sự kiện:
Mã:
const currentAlpha = document.querySelector(".currentAlpha");const currentBeta = document.querySelector(".currentBeta");const currentGamma = document.querySelector(".currentGamma");window.addEventListener("deviceorientation", (sự kiện) => { currentAlpha.textContent = event.alpha; currentBeta.textContent = event.beta; currentGamma.textContent = event.gamma;});

Để xoay khối lập phương, chúng ta thay đổi thuộc tính
transform
CSS của khối theo dữ liệu hướng thiết bị:
Mã:
const currentAlpha = document.querySelector(".currentAlpha");const currentBeta = document.querySelector(".currentBeta");const currentGamma = document.querySelector(".currentGamma");const cube = document.querySelector(".cube");window.addEventListener("deviceorientation", (event) => { currentAlpha.textContent = event.alpha; currentBeta.textContent = event.beta; currentGamma.textContent = event.gamma; cube.style.transform = `rotateX(${event.beta}deg) rotateY(${event.gamma}deg) rotateZ(${event.alpha}deg)`;});

3. Vibration API
Chúng ta hãy chuyển sự chú ý của mình sang Vibration API, không có gì ngạc nhiên khi nó cho phép truy cập vào cơ chế rung của thiết bị. Điều này rất hữu ích khi chúng ta cần cảnh báo người dùng bằng thông báo trong ứng dụng, chẳng hạn như khi một quy trình hoàn tất hoặc khi nhận được tin nhắn. Tuy nhiên, chúng ta phải sử dụng nó một cách tiết kiệm; không ai muốn điện thoại của họ nổ tung vì thông báo.Chỉ có một phương thức mà Vibration API cung cấp cho chúng ta và đó là tất cả những gì chúng ta cần:
navigator.vibrate()
.vibrate()
có sẵn trên toàn cầu từ đối tượng navigator
và sử dụng đối số về thời gian rung kéo dài tính bằng mili giây. Đối số này có thể là một số hoặc một mảng các số biểu thị cho người bảo trợ của các lần rung và tạm dừng.
Mã:
navigator.vibrate(200); // rung 200msnavigator.vibrate([200, 100, 200]); // rung 200ms, đợi 100 và rung 200ms.
Hỗ trợ trình duyệt

Bản demo API rung
Chúng ta hãy tạo một bản demo nhanh trong đó người dùng nhập số mili giây họ muốn thiết bị rung và các nút để bắt đầu và dừng rung, bắt đầu bằng mã đánh dấu:
Mã:
Mili giây: Rung Dừng
vibrate()
:
Mã:
const vibrateButton = document.querySelector(".vibrate-button");const millisecondsInput = document.querySelector("#milliseconds-input");vibrateButton.addEventListener("click", () => { navigator.vibrate(millisecondsInput.value);});
Mã:
const stopVibrateButton = document.querySelector(".stop-vibrate-button");stopVibrateButton.addEventListener("click", () => { navigator.vibrate(0);});
4. API Contact Picker
Trước đây, chỉ có các ứng dụng gốc mới có thể kết nối với "danh bạ" của thiết bị. Nhưng bây giờ chúng ta có API thứ tư và cuối cùng mà tôi muốn xem xét: API Contact Picker.API này cấp cho các ứng dụng web quyền truy cập vào danh sách liên lạc của thiết bị. Cụ thể, chúng ta có phương thức async
contacts.select()
có sẵn thông qua đối tượng navigator
, phương thức này có hai đối số sau:-
properties
: Đây là một mảng chứa thông tin mà chúng ta muốn lấy từ một thẻ liên hệ, ví dụ:"name"
,"address"
,"email"
,"tel"
và"icon"
. -
options
: Đây là một đối tượng chỉ có thể chứa thuộc tính booleanmultiple
để xác định người dùng có thể chọn một hoặc nhiều liên hệ cùng một lúc hay không.
Hỗ trợ trình duyệt
Tôi e rằng trình duyệt này gần như không hỗ trợ gì, chỉ giới hạn ở Chrome Android, Samsung Internet và trình duyệt web gốc của Android tại thời điểm tôi viết bài này.
Chọn danh bạ của người dùng
Chúng tôi sẽ tạo một bản demo khác để chọn và hiển thị danh bạ của người dùng trên trang. Một lần nữa, bắt đầu với HTML:
Mã:
Get Contacts
Contacts:
[LIST] [/LIST]
Mã:
const getContactsButton = document.querySelector(".get-contacts");const contactList = document.querySelector(".contact-list");const props = ["name", "tel", "icon"];const options = {multiple: true};
getContactsButton
.
Mã:
const getContacts = async () => { try { const contacts = await navigator.contacts.select(props, options); } catch (error) { console.error(error); }};getContactsButton.addEventListener("click", getContacts);
contactList
.
Mã:
const appendContacts = (contacts) => { contacts.forEach(({name, tel, icon}) => { const contactElement = document.createElement("li"); contactElement.innerText = `${name}: ${tel}`; contactList.appendChild(contactElement); });};const getContacts = async () => { try { const contacts = await navigator.contacts.select(props, options); appendContacts(contacts); } catch (error) { console.error(error); }};getContactsButton.addEventListener("click", getContacts);
Mã:
const getIcon = (icon) => { if (icon.length = 0) { const imageUrl = URL.createObjectURL(icon[0]); const imageElement = document.createElement("img"); imageElement.src = imageUrl; return imageElement; }};const appendContacts = (contacts) => { contacts.forEach(({name, tel, icon}) => { const contactElement = document.createElement("li"); contactElement.innerText = `${name}: ${tel}`; contactList.appendChild(contactElement); const imageElement = getIcon(icon); contactElement.appendChild(imageElement); });};const getContacts = async () => { try { const contacts = await navigator.contacts.select(props, options); appendContacts(contacts); } catch (lỗi) { console.error(lỗi); }};getContactsButton.addEventListener("click", getContacts);

Lưu ý: API Contact Picker sẽ chỉ hoạt động nếu ngữ cảnh an toàn, tức là trang được phục vụ qua
https://
hoặc wss://
URL.Kết luận
Vậy là chúng ta có bốn API web mà tôi tin rằng sẽ giúp chúng ta xây dựng các PWA hữu ích và mạnh mẽ hơn nhưng nhiều người trong chúng ta đã bỏ qua. Tất nhiên, điều này là do trình duyệt không hỗ trợ nhất quán, vì vậy tôi hy vọng bài viết này có thể nâng cao nhận thức về các API mới để chúng ta có cơ hội tốt hơn để thấy chúng trong các bản cập nhật trình duyệt trong tương lai.Chúng không thú vị sao? Chúng ta đã thấy mức độ kiểm soát của chúng ta đối với hướng của thiết bị và màn hình của thiết bị cũng như mức độ truy cập mà chúng ta có thể truy cập vào các tính năng phần cứng của thiết bị, tức là độ rung và thông tin từ các ứng dụng khác để sử dụng trong giao diện người dùng của riêng chúng ta.
Nhưng như tôi đã nói trước đó, có một loại vòng lặp vô hạn trong đó thiếu nhận thức dẫn đến thiếu hỗ trợ trình duyệt. Vì vậy, mặc dù bốn API mà chúng tôi đã đề cập rất thú vị, nhưng kết quả của bạn chắc chắn sẽ khác khi sử dụng chúng trong môi trường sản xuất. Vui lòng thận trọng và tham khảo Caniuse để biết thông tin hỗ trợ mới nhất hoặc kiểm tra thiết bị của riêng bạn bằng WebAPI Check.