Как сделать копирование текста через Clipboard API и проверить отказ

Clipboard API копирует выбранный текст в системный буфер. Запускайте запись по действию человека, дождитесь результата и предусмотрите вариант при отказе.
Что должно получиться
Человек выбирает действие рядом с нужным фрагментом, получает подтверждение и может вставить тот же текст в другое место. Если браузер не разрешил запись, интерфейс честно сообщает об этом и оставляет возможность выделить текст вручную.
Сначала определите точное содержимое копии. Это может быть адрес страницы, артикул или готовый текст. Не подменяйте видимое значение скрытым рекламным дополнением и не записывайте данные в буфер просто при открытии страницы. Действие должно иметь предсказуемый результат.
Из чего это складывается
| Часть | Назначение | Что проверить |
|---|---|---|
| Источник текста | Содержит копируемую строку | Взято актуальное значение |
| Элемент действия | Запускает копирование | Доступен с клавиатуры |
| writeText | Передаёт строку в системный буфер | Результат ожидается через await |
| Сообщение | Показывает успех или отказ | Не объявляет успех заранее |
| Ручной путь | Помогает при недоступном API | Текст можно выделить |
| Среда | Определяет доступность операции | Защищённый контекст и правила браузера |
Запись и чтение — разные операции
Для копирования вашей строки нужен navigator.clipboard.writeText(). Читать прежнее содержимое буфера для этого не требуется. Не добавляйте readText только ради проверки: это другая операция с собственными ограничениями и лишним доступом к данным.
Метод записи возвращает Promise. Успешное завершение означает, что операция записи выполнена. Оно не доказывает, что человек уже вставил текст, отправил сообщение или завершил следующий шаг вне сайта. Подтверждайте только тот результат, который действительно известен.
Как это сделать по шагам
- Выберите конкретный фрагмент для копирования. Решите, нужны ли переносы строк, пробелы и дополнительные пояснения, и покажите человеку понятный источник.
- Добавьте доступное действие рядом с фрагментом. Для обычного действия используйте нативную кнопку и сохраните видимый фокус.
- Проверьте наличие navigator.clipboard и метода writeText. На опубликованном сайте предусмотрите работу в защищённом контексте.
- Запускайте запись из обработчика действия пользователя. Не откладывайте её без необходимости на отдельную цепочку событий.
- Дождитесь завершения записи. После успеха покажите подтверждение, а при отказе объясните, что автоматическое копирование не выполнено.
- Оставьте ручное выделение исходного текста. Проверьте его на телефоне и с клавиатуры.
- Вставьте результат в тестовое поле и сравните со строкой-источником. Повторите проверку после изменения данных и в среде, где автоматическая запись недоступна.
Пример обработчика
В учебном фрагменте button — уже найденная кнопка, source — элемент с нужным обычным текстом, status — область сообщения. Обработчик можно построить так: button.addEventListener('click', async () => { try { await navigator.clipboard.writeText(source.textContent); status.textContent = 'Текст скопирован'; } catch { status.textContent = 'Не удалось скопировать'; } });
Этот фрагмент предполагает, что ссылки на элементы найдены после появления разметки и доступность API уже проверена. Если источник — поле ввода, актуальную строку обычно берут из value, а не из textContent. Для сложного фрагмента подготовьте строку явно: текст нескольких соседних элементов может соединиться не так, как вы ожидаете.
Чтение источника внутри обработчика помогает не скопировать значение, сохранённое до последнего изменения страницы. При нескольких карточках связывайте каждое действие со своим источником. Проверяйте две разные карточки подряд, чтобы обнаружить случайное копирование первой строки во всех случаях.
Защищённый контекст и отказ
Clipboard API ограничен защищённым контекстом. Для обычного опубликованного сайта основой служит HTTPS. Дополнительные требования зависят от браузера, разрешений и того, связано ли действие с текущей активацией пользователя. Успешная проверка в одной среде не гарантирует одинаковое поведение во всех остальных.
Если запись запрещена, метод может завершиться ошибкой NotAllowedError. Не предлагайте отключать защиту браузера ради одного действия. Покажите ручной путь и проверьте причину в своей тестовой среде. Для встроенной страницы отдельно учитывайте ограничения контейнера и политики доступа.
Частые ошибки
Сообщать об успехе сразу после нажатия
Нажатие запускает попытку, но не подтверждает её результат. Если показать успешное состояние до завершения Promise, человек может уйти со страницы с прежним содержимым буфера. Обновляйте сообщение в соответствующей ветке результата.
Копировать HTML вместо нужного текста
writeText работает со строкой. Передача innerHTML даст разметку как текст, а не оформленный фрагмент. Для обычной строки выбирайте текстовый источник и проверяйте переносы. Копирование нескольких представлений содержимого — отдельная задача.
Прятать отказ и оставлять только значок
Смена цвета или формы значка может остаться незамеченной. Сообщение должно быть понятно визуально и доступно вспомогательным технологиям. Для ненавязчивого сообщения можно предусмотреть подходящую область статуса; проверьте её объявление в целевой среде.
Как проверить
- Результат точно соответствует тому, что человек собирался скопировать.
- Подтверждение появляется после завершения записи, а не заранее.
- При отказе нет ложного сообщения об успехе.
- Изменение исходного значения учитывается при следующем действии.
- Соседние карточки копируют собственный текст.
- Пробелы, переносы и специальные символы сохраняются в ожидаемом виде.
- Кнопка доступна с клавиатуры, фокус не исчезает.
- Ручное выделение остаётся возможным без автоматической записи.
Проверьте состояния кнопки, ошибки JavaScript и работу сайта по HTTPS. Если нужна реализация, опишите задачу в разделе «Разработка».
Вопросы и ответы
Нужно ли читать буфер перед копированием?
Нет. Для записи известной вам строки прежнее содержимое не требуется. Не добавляйте чтение без самостоятельной понятной задачи.
Почему операция работает не во всех браузерах?
Проверьте доступность API, защищённый контекст и ограничения конкретной среды. Сохраните ручной способ вместо предположения об одинаковой поддержке.
Когда показывать подтверждение?
После успешного завершения writeText. Сам факт нажатия означает только начало попытки.
Что делать при NotAllowedError?
Сообщите об отказе, оставьте текст для выделения и проверьте условия запуска в тестовой среде. Не просите человека ослаблять защиту браузера.
Почему копируется старое значение?
Вероятно, строка была сохранена до изменения данных. Получайте актуальный источник при действии и проверьте связь с конкретной карточкой.
Можно ли считать копирование завершением следующего действия?
Нет. Запись в буфер не подтверждает вставку или отправку данных в другом приложении. Не объединяйте эти результаты в одно сообщение.
