Работа с буфером обмена в JavaScript с использованием асинхронного API Clipboard

https://alligator.io/js/async-clipboard-api/
  • Перевод
Существует новое API JavaScript, предназначенное для организации асинхронного доступа к буферу обмена с использованием спецификации, которая всё ещё находится на этапе разработки. До сих пор в веб-разработке стандартным способом копирования текста в буфер обмена является подход, предусматривающий использование метода document.execCommand. Основной недостаток этого подхода заключается в том, что это — синхронная блокирующая операция. Асинхронное API для работы с буфером обмена основано на промисах, одной из его задач является устранение этого недостатка. Оно призвано дать веб-разработчикам более простое в использовании унифицированное API для работы с буфером обмена. Кроме того, это API спроектировано с учётом возможности поддержки множества типов данных, а не только text/plain.


Надо отметить, что сейчас новое API доступно только в Chrome 66+ и поддерживает лишь копирование и вставку обычного текста. Кроме того, работает оно только тогда, когда страница загружена по HTTPS или с localhost, и только в тех случаях, когда страница открыта в текущей активной вкладке браузера.

Запись данных в буфер обмена


Запись данных в буфер обмена — простая операция, реализуемая посредством вызова метода writeText объекта clipboard с передачей ему соответствующего текста.

navigator.clipboard.writeText('Hello Alligator!')
  .then(() => {
    // Получилось!
  })
  .catch(err => {
    console.log('Something went wrong', err);
  });

Чтение данных из буфера обмена


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

navigator.clipboard.readText()
  .then(text => {
    // `text` содержит текст, прочитанный из буфера обмена
  })
  .catch(err => {
    // возможно, пользователь не дал разрешение на чтение данных из буфера обмена
    console.log('Something went wrong', err);
  });

Практический пример


Разберём простой пример взаимодействия с буфером обмена из JavaScript. Он будет работать лишь в поддерживаемых браузерах. Если хотите, можете своими силами доработать его, добавив механизмы, позволяющие ему функционировать в браузерах, которые пока не поддерживают API Clipboard. Посмотреть, как всё это работает, можно на странице оригинала статьи, в разделе Simple Demo.

Рассмотрим HTML-разметку.

<div>
  <input type="text" class="to-copy" placeholder="Type something..." aria-label="Type something">
  <button class="write-btn">Copy to clipboard</button>
</div>

<div>
  <h3 class="clipboard-results"></h3>
  <button class="read-btn">Paste from clipboard</button>
</div>

А вот — JS-код, который отвечает за работу с буфером обмена.

const readBtn = document.querySelector('.read-btn');
const writeBtn = document.querySelector('.write-btn');

const resultsEl = document.querySelector('.clipboard-results');
const inputEl = document.querySelector('.to-copy');

readBtn.addEventListener('click', () => {
  navigator.clipboard.readText()
    .then(text => {
      resultsEl.innerText = text;
    })
    .catch(err => {
      console.log('Something went wrong', err);
    })
});

writeBtn.addEventListener('click', () => {
  const inputValue = inputEl.value.trim();
  if (inputValue) {
    navigator.clipboard.writeText(inputValue)
      .then(() => {
        inputEl.value = '';
        if (writeBtn.innerText !== 'Copied!') {
          const originalText = writeBtn.innerText;
          writeBtn.innerText = 'Copied!';
          setTimeout(() => {
            writeBtn.innerText = originalText;
          }, 1500);
        }
      })
      .catch(err => {
        console.log('Something went wrong', err);
      })
  }
});

Как видите, всё тут устроено очень просто. Единственное место, над которым пришлось немного поработать — это код для работы с кнопкой копирования, где мы сначала проверяем, что нам есть что копировать, а затем ненадолго меняем текст кнопки и очищаем поле ввода после успешного завершения операции копирования.

Будущее API Clipboard


Рассматриваемое API описывает более общие методы write и read, позволяющие работать с данными, отличающимися от обычного текста, в частности — с изображениями. Например, использование метода read может выглядеть так:

navigator.clipboard.read().then(({ items }) => {
  items.forEach(item => {
    console.log(item.type);
    // делаем что-то с полученными данными
  });
});

Обратите внимание на то, что эти методы пока не поддерживаются ни одним из существующих браузеров.

Проверка возможностей браузера


Предположим, вы создали веб-проект, некоторые функции которого полагаются на возможности по работе с буфером обмена. Учитывая то, что API Clipboard в настоящий момент поддерживает лишь один браузер, в подобном проекте нелишним будет предусмотреть альтернативные способы работы с буфером обмена. Например — метод, основанный на execCommand. Для того чтобы понять, поддерживает ли браузер то, что нам нужно, можно просто проверить наличие объекта clipboard в глобальном объекте navigator:

if (navigator.clipboard) {
  // поддержка имеется, включить соответствующую функцию проекта.
} else {
  // поддержки нет. Придётся пользоваться execCommand или не включать эту функцию.
}

Итоги


Полагаем, унифицированный механизм работы с буфером обмена — это полезная возможность, поддержка которой в обозримом будущем появится во всех основных браузерах. Если данная тема вам интересна — взгляните на этот материал Джейсона Миллера.

Уважаемые читатели! Какие варианты использования API Clipboard кажутся вам самыми перспективными?

  • +14
  • 3,7k
  • 7
RUVDS.com 528,57
RUVDS – хостинг VDS/VPS серверов
Поделиться публикацией
Похожие публикации
Комментарии 7
  • +2
    Какие варианты использования API Clipboard кажутся вам самыми перспективными?

    Пароли тырить у тех, кто доверился и кликнул «разрешить сайту копаться в моем буфере обмена». Для всех остальных есть клик правой кнопкой и «Paste».
    • 0
      Первое, что я подумал, ещё даже не приступая к чтению этой заметки, так это то, что чрезвычайно продвинутые программисты (в народе просто хакеры), будут усиленно добывать чужие секреты
    • +2
      В чём глубокий смысл асинхронного API буфера обмена? Разве операции чтения и записи могут занимать большое время?
      • 0

        Смысл в том, что это вызов внешней системы, за пределами страницы. Все такие вызовы обычно делают асинхронными.

        • 0
          В теории да. От большой и тяжелой картинки до генерации данных на лету приложением, в котором до этого нажали Copy.
          • +1

            Смысл в том, чтобы спросить у юзера разрешения, не заблокировав при этом страницу.

            • 0
              в винде точно могут.
              если лежит объект и у него запрашивают только текст, там всякие внешние вызовы возможны и прочее.
              пробовал как то в этом копаться — довольно мудрено.

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

            Самое читаемое