Как получить доступ к контактам из адресной книги

Иногда вы хотите, чтобы пользователи вашего приложения могли выбрать один из своих контактов для отправки сообщения по электронной почте или через приложение чата, или помочь им узнать, кто из их контактов уже присоединился к социальной платформе.

Современный способ

Использование API выбора контактов

Чтобы получить контакты из адресной книги, вам необходимо использовать API выбора контактов , который позволяет пользователям выбирать записи из своего списка контактов и делиться ограниченными сведениями о выбранных записях с вашим приложением. Доступны несколько свойств, таких как name , email , tel , address и icon . Чтобы узнать о конкретно поддерживаемых свойствах, вызовите navigator.contacts.getProperties() . Чтобы разрешить пользователю выбирать несколько контактов, передайте {multiple: true} в качестве второго параметра navigator.contacts.select() .

Поддержка браузера

  • Икс
  • Икс
  • Икс
  • Икс

Источник

API выбора контактов доступен в версии Chrome для Android, начиная с версии 80.

Классический способ

Использование обычной формы

Альтернативный метод — использовать обычную форму, позволяющую пользователю ввести данные контакта.

Поддержка браузера

  • 1
  • 12
  • 1
  • ≤4

Источник

Прогрессивное улучшение

Если API выбора контактов поддерживается, скройте статические поля формы и вместо них покажите кнопку выбора.

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}`;
    }
  });
}

дальнейшее чтение

Демо

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}`
    }
  });
}