Существует новое 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 кажутся вам самыми перспективными?
Автор: ru_vds