- PVSM.RU - https://www.pvsm.ru -

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

Существует новое API JavaScript, предназначенное для организации асинхронного доступа к буферу обмена с использованием спецификации [1], которая всё ещё находится на этапе разработки. До сих пор в веб-разработке стандартным способом копирования текста в буфер обмена является подход, предусматривающий использование метода document.execCommand [2]. Основной недостаток этого подхода заключается в том, что это — синхронная блокирующая операция. Асинхронное API для работы с буфером обмена основано на промисах [3], одной из его задач является устранение этого недостатка. Оно призвано дать веб-разработчикам более простое в использовании унифицированное API для работы с буфером обмена. Кроме того, это API спроектировано с учётом возможности поддержки множества типов данных, а не только text/plain.

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


Надо отметить, что сейчас новое 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. Посмотреть, как всё это работает, можно на странице [4] оригинала статьи, в разделе 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 или не включать эту функцию.
}

Итоги

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

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

Автор: ru_vds

Источник [6]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/javascript/280193

Ссылки в тексте:

[1] спецификации: https://www.w3.org/TR/clipboard-apis/#async-clipboard-api

[2] document.execCommand: https://alligator.io/js/copying-to-clipboard/

[3] промисах: https://alligator.io/js/promises-es6/

[4] странице: https://alligator.io/js/async-clipboard-api/

[5] этот материал: https://developers.google.com/web/updates/2018/03/clipboardapi

[6] Источник: https://habr.com/post/358494/?utm_source=habrahabr&utm_medium=rss&utm_campaign=358494