Cách truy cập danh bạ từ sổ địa chỉ

Đôi khi, bạn muốn cho phép người dùng ứng dụng của mình chọn một người liên hệ để nhắn tin qua email hoặc ứng dụng trò chuyện, hoặc giúp họ khám phá những người liên hệ nào đã tham gia một nền tảng xã hội.

Cách làm hiện đại

Sử dụng API Trình chọn người liên hệ

Để lấy danh bạ từ sổ địa chỉ, bạn cần sử dụng Contact Picker API. API này cho phép người dùng chọn các mục trong danh sách liên hệ và chia sẻ thông tin chi tiết có giới hạn của các mục đã chọn với ứng dụng của bạn. Một số thuộc tính như name, email, tel, addressicon hiện có sẵn. Để tìm hiểu về các thuộc tính được hỗ trợ cụ thể, hãy gọi navigator.contacts.getProperties(). Để cho phép người dùng chọn nhiều người liên hệ, hãy truyền {multiple: true} làm tham số thứ hai của navigator.contacts.select().

Browser Support

  • Chrome: not supported.
  • Edge: not supported.
  • Firefox: not supported.
  • Safari: not supported.

Source

API Trình chọn người liên hệ có trong phiên bản Chrome dành cho Android từ phiên bản 80.

Cách cổ điển

Sử dụng biểu mẫu thông thường

Phương pháp dự phòng là sử dụng một biểu mẫu thông thường để người dùng nhập thông tin chi tiết của người liên hệ.

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 3.

Source

Cải tiến tăng dần

Nếu Contact Picker API được hỗ trợ, hãy ẩn các trường biểu mẫu tĩnh và thay vào đó, hiển thị một nút chọn.

const button = document.querySelector('button');
const name = document.querySelector('.name');
const address = document.querySelector('.address');
const email = document.querySelector('.email');
const tel = document.querySelector('.tel');
const pre = document.querySelector('pre');
const autofills = document.querySelectorAll('.autofill');

if ('contacts' in navigator) {
  button.hidden = false;
  for (const autofill of autofills) {
    autofill.parentElement.style.display = 'none';
  }
  address.parentElement.style.display = 'block';
  button.addEventListener('click', async () => {
    const props = ['name', 'email', 'tel', 'address'];
    const opts = { multiple: false };
    try {
      const [contact] = await navigator.contacts.select(props, opts);
      name.value = contact.name;
      address.value = contact.address;
      tel.value = contact.tel;
      email.value = contact.email;
    } catch (err) {
      pre.textContent = `${err.name}: ${err.message}`;
    }
  });
}

Tài liệu đọc thêm

Bản minh hoạ

HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link
      rel="icon"
      href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🎉</text></svg>"
    />
    <title>How to access contacts from the address book</title>
  </head>
  <body>
    <h1>How to access contacts from the address book</h1>

    <p>Ship your order as a present to a friend.</p>
    <button hidden type="button">Open address book</button>
    <pre></pre>

    <label> Name <input class="name" autocomplete="name"></label>

    <label hidden>Address <input class="address" required></label>

    <label>Street <input class="autofill" autocomplete="address-line1" required></label>

    <label>City <input class="autofill" autocomplete="address-level2" required></label>

    <label>State / Province / Region (optional) <input class="autofill" autocomplete="address-level1"></label>

    <label>ZIP / Postal code (optional) <input class="autofill" autocomplete="postal-code"></label>

    <label>Country <input class="autofill" autocomplete="country"></label>

    <label>Email<input class="email" autocomplete="email"></label>

    <label>Telephone<input class="tel" autocomplete="tel"></label>
  </body>
</html>

CSS


        html {
  box-sizing: border-box;
  font-family: system-ui, sans-serif;
  color-scheme: dark light;
}

*, *:before, *:after {
  box-sizing: inherit;
}

body {
  margin: 1rem;
}

input {
  display: block;
  margin-block-end: 1rem;
}
        

JS


        const button = document.querySelector('button');
const name = document.querySelector('.name')
const address = document.querySelector('.address')
const email = document.querySelector('.email')
const tel = document.querySelector('.tel')
const pre = document.querySelector('pre')
const autofills = document.querySelectorAll('.autofill')

if ('contacts' in navigator) {
  button.hidden = false;
  for (const autofill of autofills) {
    autofill.parentElement.style.display = 'none'
  }
  address.parentElement.style.display = 'block';
  button.addEventListener('click', async () => {
    const props = ['name', 'email', 'tel', 'address'];
    const opts = {multiple: false};
    try {
      const [contact] = await navigator.contacts.select(props, opts);
      name.value = contact.name;
      address.value = contact.address;
      tel.value = contact.tel
      email.value = contact.email;
    } catch (err) {
      pre.textContent = `${err.name}: ${err.message}`
    }
  });
}