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

Вырезать и копировать в буффер с помощью JavaScript

Начиная с IE10 добавлена поддержка команд «Копировать» и «Вырезать» с помощью метода Document.execCommand() [1]. Так же эти методы доступны в Chrome начиная с версии 43.

Любой текст выделенный в браузере при выполнении одной из этих команд будет скопирован или вырезан в буфер обмена пользователя. Это позволяет предложить пользователю простой метод выделить часть текста и скопировать в буфер обмена.

Это становится крайне полезным в сочетании с API программного выделения текста [2], что бы задать что скопировать в буфер. Примеры будут рассмотрены в этой статье.

Примеры

Для примера, давайте добавим кнопку которая скопирует email адрес в буфер обмена.

Мы добавим email адрес, в наш HTML, с кнопкой клик по которой будет инициировать копирование email:

<p>Email me at <a class="js-emaillink" href="mailto:matt@example.co.uk">matt@example.co.uk</a></p>

<p><button class="js-emailcopybtn"><img src="./images/copy-icon.png" /></button></p>

Тогда, в наш JavaScript, мы добавим обработчик клика по кнопке, который выделит email из содержимого ссылки js-emaillink, выполнит команду копирования, так что бы адрес электронной почты оказался в буфере пользователя и после этого снять выделение с электронной почты, так что пользователь даже не увидит выделение.

var copyEmailBtn = document.querySelector('.js-emailcopybtn');  
copyEmailBtn.addEventListener('click', function(event) {  
  // Выборка ссылки с электронной почтой 
  var emailLink = document.querySelector('.js-emaillink');  
  var range = document.createRange();  
  range.selectNode(emailLink);  
  window.getSelection().addRange(range);  
    
  try {  
    // Теперь, когда мы выбрали текст ссылки, выполним команду копирования
    var successful = document.execCommand('copy');  
    var msg = successful ? 'successful' : 'unsuccessful';  
    console.log('Copy email command was ' + msg);  
  } catch(err) {  
    console.log('Oops, unable to copy');  
  }  
    
  // Снятие выделения - ВНИМАНИЕ: вы должны использовать
  // removeRange(range) когда это возможно
  window.getSelection().removeAllRanges();  
});

Здесь используется метод API выделения [2], window.getSelection() [3], что бы программно выделить текст внутри ссылки, который мы хотим скопировать в буфер обмена пользователя. После вызова document.execCommand() мы можем снять выделение с помощью window.getSelection().removeAllRanges() [4].
Если вы хотите проверить что все прошло успешно, то вы можете рассмотреть результат возвращаемый функцией document.execCommand(). Результат будет false если функция не поддерживается или отключена. Мы «обвернули» execCommand() в try...catch, т.к. команды «вырезать» и «копировать» в некоторых случаях могут вернуть ошибку [5].

Команда «вырезать» может быть использована для текстовых полей ввода, там, где вы хотите удалить текст и поместить этот текст в буфер.

Использование textarea и кнопки:

<p><textarea class="js-cuttextarea">Hello I'm some text</textarea></p>
  
<p><button class="js-textareacutbtn" disable>Cut Textarea</button></p>

Мы можем сделать следующее, что бы «вырезать» содержимое:

var cutTextareaBtn = document.querySelector('.js-textareacutbtn');

cutTextareaBtn.addEventListener('click', function(event) {  
  var cutTextarea = document.querySelector('.js-cuttextarea');  
  cutTextarea.select();

  try {  
    var successful = document.execCommand('cut');  
    var msg = successful ? 'successful' : 'unsuccessful';  
    console.log('Cutting text command was ' + msg);  
  } catch(err) {  
    console.log('Oops, unable to cut');  
  }  
});

queryCommandSupported и queryCommandEnabled

Перед вызовом document.execCommand() вы должны убедится что эти API поддерживаются с помощью document.queryCommandSupported() [6]. В примере выше, мы могли бы заблокировать кнопку, по результатам проверки совместимости, например, так:

copyEmailBtn.disabled = !document.queryCommandSupported('copy');

Отличие между queryCommandSupported() [6] и queryCommandEnabled() [7] в том, что команды «копировать» и «вырезать» могут поддерживаться браузером, но если текст не выделен, то они не будут доступны. Это удобно в том случае если вы не выбрали фрагмент текста программно и хотите что бы команда отработала ожидаемо, в противном случае показать сообщение пользователю.

Совместимость с браузерами

IE 10+, Chrome 43+ и Opera 29+

Firefox поддерживает данные функции, но требует изменения настроек (см. тут [1]) (Примечание переводчика: при этом довольно давно. Была даже функция чтения из буфера обмена, заблокированная по умолчанию в целях безопасности). Без этого Firefox вернет ошибку.

Safari не поддерживает данные команды.

Известные проблемы

Автор: edejin

Источник [11]


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

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

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

[1] Document.execCommand(): https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand

[2] API программного выделения текста: https://developer.mozilla.org/en-US/docs/Web/API/Selection

[3] window.getSelection(): https://developer.mozilla.org/en-US/docs/Web/API/Window/getSelection

[4] window.getSelection().removeAllRanges(): https://developer.mozilla.org/en-US/docs/Web/API/Selection/removeAllRanges

[5] могут вернуть ошибку: https://dvcs.w3.org/hg/editing/raw-file/tip/editing.html#the-copy-command

[6] document.queryCommandSupported(): https://developer.mozilla.org/en-US/docs/Web/API/Document/queryCommandSupported

[7] queryCommandEnabled(): https://dvcs.w3.org/hg/editing/raw-file/tip/editing.html#querycommandenabled()

[8] всегда возвращает false: http://crbug.com/476508

[9] Вызов queryCommandSupported() из консоли разработчика всегда возвращает false.: http://crbug.com/475868

[10] вырезание текста доступно только если текст был выделен программно: http://crbug.com/476848

[11] Источник: http://habrahabr.ru/post/256027/