Event.clipboardData.setData в событии копирования

Я просмотрел много постов, но не смог найти четкого текущего ответа на следующие два вопроса, так как кажется, что стандарты и поддержка браузеров постоянно меняются.

  1. Является ли законной операцией в соответствии со стандартом изменение буфера обмена с помощью event.clipboardData.setData в обработчике события "copy"?

  2. Правильно ли это поддерживается в последних версиях Chrome/FF/Safari/IE/Chrome iOS/Android/iPhone?

Ответ 1

API буфера обмена действительно активно разрабатывались с 2016 года, но с тех пор ситуация стабилизировалась:

Использование event.clipboardData.setData() поддерживается

Изменение буфера обмена с помощью event.clipboardData.setData() внутри обработчика событий 'copy' разрешено спецификацией (если событие не является синтетическим).

Обратите внимание, что вам нужно запретить действие по умолчанию в обработчике событий, чтобы предотвратить изменение ваших изменений браузером:

document.addEventListener('copy', function(e){
  e.clipboardData.setData('text/plain', 'foo');
  e.preventDefault(); // default behaviour is to copy any selected text
});

Для запуска события копирования используйте execCommand

Если вам нужно инициировать событие копирования (а не просто обрабатывать запросы на копирование, сделанные пользователем через пользовательский интерфейс браузера), вы должны использовать document.execCommand('copy'). Он будет работать только в определенных обработчиках, таких как обработчик click:

document.getElementById("copyBtn").onclick = function() {
  document.execCommand('copy');
}

Современные браузеры поддерживают оба метода

https://github.com/garykac/clipboard/blob/master/clipboard.md  имеет таблицу совместимости для execCommand(cut / copy / paste).

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

Больше ресурсов

TestCase

window.onload = function() {
  document.addEventListener('copy', function(e){
    console.log("copy handler");
    if (document.getElementById("enableHandler").checked) {
      e.clipboardData.setData('text/plain', 'Current time is ' + new Date());
      e.preventDefault(); // default behaviour is to copy any selected text
    }
    // This is just to simplify testing:
    setTimeout(function() {
      var tb = document.getElementById("target");
      tb.value = "";
      tb.focus();
    }, 0);
  });
  document.getElementById("execCopy").onclick = function() {
    document.execCommand('copy'); // only works in click handler or other user-triggered thread
  }
  document.getElementById("synthEvt").onclick = function() {
    var e = new ClipboardEvent("copy", {dataType: "text/plain", data:"bar"});
    document.dispatchEvent(e);
  }
}
<html>
<input id="enableHandler" type="checkbox" checked>
<label for="enableHandler">Run clipboardData.setData('text/plain', ...) in the "copy" handler</label>
<p>Try selecting this text and triggering a copy using</p>
<ul>
    <li><button id="execCopy">document.execCommand('copy')</button> - should work.</li>
    <li><button id="synthEvt">document.dispatchEvent(clipboardEvent)</button> - should NOT work</li>
    <li>with keyboard shortcut - should work</li>
    <li>or from the context menu - should work</li>
</ul>
<p>If the "copy" handler was triggered, the focus will move to the textbox below automatically, so that you can try pasting from clipboard:</p>
<input type="text" id="target" size="80">

Ответ 2

Вы также можете просто превратить его в функцию, которая вызывает свой собственный обработчик и удаляет его

function copyStringToClipboard (string) {
    function handler (event){
        event.clipboardData.setData('text/plain', string);
        event.preventDefault();
        document.removeEventListener('copy', handler, true);
    }

    document.addEventListener('copy', handler, true);
    document.execCommand('copy');
}

Ответ 3

Свяжите идентификатор элемента с событием копирования, а затем получите выделенный текст. Вы можете заменить или изменить текст. Получите буфер обмена и установите новый текст. Чтобы получить точное форматирование, вам нужно установить тип как "text/hmtl". Вы также можете привязать его к документу вместо элемента.

 $(ElementId).bind('copy', function(event) {
    var selectedText = window.getSelection().toString(); 
    selectedText = selectedText.replace(/\u200B/g, "");

    clipboardData = event.clipboardData || window.clipboardData || event.originalEvent.clipboardData;
    clipboardData.setData('text/html', selectedText);

    event.preventDefault();
  });