Проблема
Обычно копирование текста происходит так (взято отсюда):
- Создайте элемент
<textarea>
, который будет добавлен к документу. Установите егоvalue
на строку, которую мы хотим скопировать в буфер обмена. - Добавьте указанный элемент
<textarea>
к текущему HTML-документу. - Используйте
HTMLInputElement.select()
для выбора содержимого элемента<textarea>
. - Используйте
document.execCommand('copy')
, чтобы скопировать содержимое<textarea>
в буфер обмена. - Удалите элемент
<textarea>
из документа.
Код выглядит следующим образом:
function copyToClipboard(text) { const el = document.createElement('textarea'); el.value = text; document.body.appendChild(el); el.select(); document.execCommand('copy'); document.body.removeChild(el); };
При таком подходе есть две проблемы:
- Возможно некоторое мигание из-за временного элемента
<textarea>
. - Он отменит выбор всего, что выбирает пользователь.
Мы можем обойти и то, и другое, но функция станет намного длиннее.
Решение
Когда пользователь инициирует действие копирования, пользовательский агент запускает копирование имени события буфера обмена.
— Спецификация W3C
- Используйте
addEventListener
, чтобы прикрепить наш пользовательский обработчик событий, который заменит текущие данные нашим текстом. - Используйте
document.execCommand('copy')
для запуска действия копирования. - Используйте
removeEventListener
, чтобы удалить наш обработчик событий.
function copyToClipboard(text) { const listener = function(ev) { ev.preventDefault(); ev.clipboardData.setData('text/plain', text); }; document.addEventListener('copy', listener); document.execCommand('copy'); document.removeEventListener('copy', listener); }
Бонус
Вы даже можете скопировать форматированный текст!
function copyRichText(text) { const listener = function(ev) { ev.preventDefault(); ev.clipboardData.setData('text/html', text); ev.clipboardData.setData('text/plain', text); }; document.addEventListener('copy', listener); document.execCommand('copy'); document.removeEventListener('copy', listener); } copyRichText('<i>Markup</i> <b>text</b>. Paste me into a rich text editor.');
Совместимость с браузером
Согласно веб-документам MDN, это должно работать во всех основных браузерах, кроме Internet Explorer.
Первоначально опубликовано на https://komsciguy.com 23 мая 2020 г.