Javascript how to copy to clipboard

JavaScript. Работа с буфером, Ctrl+C Ctrl+V

Как копировать в буфер картинки. Какие типы данных можно класть в буфер. Поддержка кастомных типов. Как сделать свои кнопки копировать/вставить.

Задача

Сделать копирование для редактора блок-схем dgrm.net.

  • Копировать можно между вкладками.
  • Можно копировать в Word/Google docs, тогда схема вставляется как картинка.
  • Должны работать горячие клавиши Ctrl+C, Ctrl+V, Ctrl+X.
  • Свои кнопки копировать/вставить, чтобы можно было копировать мышкой.
  • Поддержка мобильных.

Варианты API работы с буфером

document.execCommand(‘copy’) не работает

Это API устарело и не работает. Не пытайтесь с его помощью обойти ограничения других API.

Работа с буфером в обработчиках событий ‘copy’, ‘paste’, ‘cut’

document.addEventListener('copy', evt => < evt.preventDefault(); evt.clipboardData.setData('text/plain', 'text to clipboard'); >);

Листинг 1. Пишем в буфер на событии “вставить”

В этом варианте нет возможности сделать свою кнопку “копировать”, пользователь должен нажать Ctrl+C.

btn.addEventListener('click', async _ => await navigator.clipboard.writeText('text to clipboard') );

Листинг 2. Пишем в буфер по клику на кнопке

Можно сделать свою кнопку “копировать”. Работает во всех браузерах и на мобильных.
В Safari есть ограничение: нельзя использовать в callback-ах. Так в Safari не работает:

btn.addEventListener('click', async _ => // create png from svg svgToPng( svg, // callback async png => await navigator.clipboard.write(. )) );

Листинг 3. Не работает в Safari. Нельзя использовать navigator.clipboard в callback-ах. Как писать картинку в буфер в следующем разделе.

Это ограничение безопасности: когда придет callback не понятно, пользователь может уже и передумал копировать.

Можно сделать так: строку гарантированно пишем в буфер, если браузер разрешит запишем картинку.

// guaranteed clipboard write await navigator.clipboard.writeText('text to clipboard'); // try to write img // if ok -> clipboard will be overwritten try < // create png from svg svgToPng( svg, // callback async png =>await navigator.clipboard.write(. )); > catch

Листинг 4. Запись текста в буфер гарантирована, если браузер разрешит запишем картинку

Как записать картинку в буфер

await navigator.clipboard.write([new window.ClipboardItem(< 'image/png': Promise.resolve(png), // png is Blob 'text/plain': Promise.resolve(new Blob(['text to clipboard'], < type: 'text/plain' >)) >)]);

Листинг 5. Запись картинки и альтернативного текста в буфер.

В буфер можно записать одновременно несколько типов данных. Например, картинку и текст. Если вставить в Word — вставится картинка, если в блокнот — текст.

Можно записывать такие типы:

Некоторые браузеры поддерживают больше типов. Эти три работают везде.

Копировать в буфер можно только png. Другие форматы картинок не поддерживаются.
При копировании браузер “очищает” png. Для безопасности браузер удаляет из png метаданные.

Неприятность для dgrm.net. Dgrm.net хранит в метаданных описание схемы. Благодаря метаданным можно открыть картинку на редактирование — рис 2.

Читайте также:  Поменять местами значения двух переменных питон

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

‘text/plain’ из буфера можно вставить куда угодно. Хорошо использовать свой тип данных, который читает только ваше приложение. Например ‘text/dgrm’.

Для безопасности браузер связывает самодельный тип с доменом. Таким образом посторонний сайт не прочитает из буфера ваш тип данных.

Не все браузеры поддерживают самодельные типы. В Chrome можно использовать кастомные типы, они обязательно должны иметь префикс ‘web ’ -> ‘web text/dgrm’.

Не все браузеры позволяют записать не ‘text/plain’ в буфер с помощью navigator.clipboard.write. Разрешают только в обработчиках событий ‘copy’, ‘cut’. Т.е. свою кнопку “копировать” нельзя сделать.

В итоге остановился на navigator.clipboard.writeText который везде работает.

Чтение из буфера

Чтение буфера еще опаснее чем запись. Еще больше ограничений. В FireFox читать можно только в обработчике события ‘paste’. Свою кнопку “вставить” сделать нельзя, нужно чтобы пользователь нажал Ctrl V.

document.addEventListener('paste', evt => < const txt = evt.clipboardData.getData('text/plain'); >);

Листинг 6. Чтение из буфера на событии ‘paste’

В других браузерах можно использовать navigator.clipboard API.

btn.addEventListener('click', async _ => await navigator.clipboard.readText() );

Листинг 7. Чтение из буфера по кнопке

Браузер запросит разрешение пользователя. iOS Safari будет спрашивать при каждом вызове navigator.clipboard.readText.

О редакторе dgrm.net

Dgrm.net — быстрый редактор без лишних кнопок.

Развиваю редактор. Анонсы обновлений начал писать в телеграм.

Попробуйте, напишите что нравится/не нравится. Все читаю, веду список предложений.

Источник

How to Copy Text to the Clipboard with JavaScript

Joel Olawanle

Joel Olawanle

How to Copy Text to the Clipboard with JavaScript

When you’re building advanced web pages and applications, you’ll sometimes want to add the copy feature. This lets your users simply click a button or icon to copy text rather than highlighting the text and clicking a couple of buttons on the keyboard.

This feature is mostly used when someone needs to copy an activation code, recovery key, code snippet, and so on. You can also add functionalities like an alert or text on the screen (which could be a modal) to inform the user that the text has been copied to their clipboard.

Previously you would’ve handled this with the document.execCommand() command, but that is deprecated (no longer recommended). You can now use the Clipboard API, which allows you to respond to clipboard commands (cut, copy, and paste) and asynchronously read from and write to the system clipboard.

In this article, you will learn how to write (copy) text and images to the clipboard with the Clipboard API.

In case you are in a rush, here is the code:

Hello World

If you are not in a rush, let’s understand more about the Clipboard API and see how this works with a demo project.

How to Check the Browser’s Permissions

It is important to know that the Clipboard API is only supported for pages served over HTTPS. You should also check for browser permissions before attempting to write to the clipboard to verify if you have the write access. You can do this with the navigator.permissions query:

navigator.permissions.query(< name: "write-on-clipboard" >).then((result) => < if (result.state == "granted" || result.state == "prompt") < alert("Write access granted!"); >>); 

How to Copy Text to the Clipboard

To copy text with the new Clipboard API, you will use the asynchronous writeText() method. This method accepts only one parameter — the text to copy to your clipboard. This can be a string, a template literal holding variables and other strings, or a variable used to hold a string.

Читайте также:  Add attributes to an html element

Since this method is asynchronous, it returns a promise. This promise is resolved if the clipboard has been updated successfully, and is rejected otherwise:

navigator.clipboard.writeText("This is the text to be copied").then(() => < console.log('Content copied to clipboard'); /* Resolved - text copied to clipboard successfully */ >,() => < console.error('Failed to copy'); /* Rejected - text failed to copy to the clipboard */ >); 

You can also use async/await alongside try/catch:

async function copyContent() < try < await navigator.clipboard.writeText('This is the text to be copied'); console.log('Content copied to clipboard'); /* Resolved - text copied to clipboard successfully */ >catch (err) < console.error('Failed to copy: ', err); /* Rejected - text failed to copy to the clipboard */ >> 

Copy text to clipboard example

Here is a demo showing how it works using a real-life example. In this example, we’re fetching quotes from a public quote API. Then when you click the copy icon, the quote and its author get copied, showing that you can adjust what you copy into the writeText() method.

See the Pen copy text JS by Olawanle Joel (@olawanlejoel) on CodePen.

Wrapping Up

In this article, you have learned how to copy text to the clipboard with JavaScript using the Clipboard API without having to think outside the box or install any JavaScript library.

Embark on a journey of learning! Browse 200+ expert articles on web development. Check out my blog for more captivating content from me.

Источник

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

Существует новое 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.

 

А вот — 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); >) > >);

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

Читайте также:  Распарсить xml файл python

Будущее 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 кажутся вам самыми перспективными?

Источник

Оцените статью