it-swarm.com.ru

Как мне скопировать в буфер обмена в JavaScript?

Каков наилучший способ скопировать текст в буфер обмена? (Мульти-браузер)

Я пытался: 

function copyToClipboard(text) {
    if (window.clipboardData) { // Internet Explorer
        window.clipboardData.setData("Text", text);
    } else {  
        unsafeWindow.netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");  
        const clipboardHelper = Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper);  
        clipboardHelper.copyString(text);
    }
}

но в Internet Explorer выдает синтаксическую ошибку. В Firefox написано unsafeWindow is not defined.

Хороший трюк без вспышки: Как Trello получает доступ к буферу обмена пользователя?

2858
Santiago Corredoira

Обзор

Существует три основных API браузера для копирования в буфер обмена:

  1. Async Clipboard API[navigator.clipboard.writeText]
    • Текстовая часть доступна в Chrome 66 (март 2018)
    • Доступ асинхронный и использует Обещания JavaScript , могут быть написаны так, чтобы пользовательские запросы безопасности (если отображаются) не прерывали JavaScript на странице.
    • Текст может быть скопирован в буфер обмена непосредственно из переменной.
    • Поддерживается только на страницах, обслуживаемых по HTTPS.
    • В Chrome 66 страниц в активных вкладках можно писать в буфер обмена без разрешения подсказок.
  2. document.execCommand('copy')
    • Большинство браузеров поддерживают это по состоянию на апрель 2015 года (см. «Поддержка браузеров» ниже).
    • Доступ является синхронным, то есть останавливает JavaScript на странице до завершения, включая отображение и взаимодействие пользователя с любыми запросами безопасности.
    • Текст читается из DOM и помещается в буфер обмена.
    • Во время тестирования ~ апреля 2015 года только Internet Explorer был отмечен как отображающий запросы разрешений при записи в буфер обмена.
  3. Переопределение события копирования
    • См. Документацию по API буфера обмена для Переопределение события копирования .
    • Позволяет изменить то, что появляется в буфере обмена из любого события копирования, может включать в себя другие форматы данных, кроме обычного текста.
    • Здесь не рассматривается, так как это не дает прямого ответа на вопрос.

Общие замечания по разработке

Не ожидайте, что команды, связанные с буфером обмена, будут работать, пока вы тестируете код в консоли. Обычно страница должна быть активной (Async Clipboard API) или требует взаимодействия с пользователем (например, щелчок пользователя), чтобы разрешить (document.execCommand('copy')) доступ к буферу обмена, подробнее см. Ниже.

Async + Fallback

Из-за уровня поддержки браузером нового Async Clipboard API вы, вероятно, захотите вернуться к методу document.execCommand('copy'), чтобы получить хорошее покрытие браузера.

Вот простой пример:

function fallbackCopyTextToClipboard(text) {
  var textArea = document.createElement("textarea");
  textArea.value = text;
  document.body.appendChild(textArea);
  textArea.focus();
  textArea.select();

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

  document.body.removeChild(textArea);
}
function copyTextToClipboard(text) {
  if (!navigator.clipboard) {
    fallbackCopyTextToClipboard(text);
    return;
  }
  navigator.clipboard.writeText(text).then(function() {
    console.log('Async: Copying to clipboard was successful!');
  }, function(err) {
    console.error('Async: Could not copy text: ', err);
  });
}

var copyBobBtn = document.querySelector('.js-copy-bob-btn'),
  copyJaneBtn = document.querySelector('.js-copy-jane-btn');

copyBobBtn.addEventListener('click', function(event) {
  copyTextToClipboard('Bob');
});


copyJaneBtn.addEventListener('click', function(event) {
  copyTextToClipboard('Jane');
});
<div style="display:inline-block; vertical-align:top;">
  <button class="js-copy-bob-btn">Set clipboard to BOB</button><br /><br />
  <button class="js-copy-jane-btn">Set clipboard to JANE</button>
</div>
<div style="display:inline-block;">
  <textarea class="js-test-textarea" cols="35" rows="4">Try pasting into here to see what you have on your clipboard:

  </textarea>
</div>

Обратите внимание, что этот фрагмент не работает должным образом во встроенном предварительном просмотре Stack Overflow. Попробуйте его здесь: https://codepen.io/DeanMarkTaylor/pen/RMRaJX?editors=1011

Async Clipboard API

Обратите внимание, что в Chrome 66 есть возможность «запросить разрешение» и проверить доступ к буферу обмена через API разрешений.

var text = "Example text to appear on clipboard";
navigator.clipboard.writeText(text).then(function() {
  console.log('Async: Copying to clipboard was successful!');
}, function(err) {
  console.error('Async: Could not copy text: ', err);
});

document.execCommand ( 'копия')

Остальная часть этого поста посвящена нюансам и деталям API document.execCommand('copy').

Поддержка браузера

Поддержка JavaScript document.execCommand('copy') увеличилась, см. Ссылки ниже для обновлений браузера:

Простой пример

var copyTextareaBtn = document.querySelector('.js-textareacopybtn');

copyTextareaBtn.addEventListener('click', function(event) {
  var copyTextarea = document.querySelector('.js-copytextarea');
  copyTextarea.focus();
  copyTextarea.select();

  try {
    var successful = document.execCommand('copy');
    var msg = successful ? 'successful' : 'unsuccessful';
    console.log('Copying text command was ' + msg);
  } catch (err) {
    console.log('Oops, unable to copy');
  }
});
<p>
  <button class="js-textareacopybtn" style="vertical-align:top;">Copy Textarea</button>
  <textarea class="js-copytextarea">Hello I'm some text</textarea>
</p>

Сложный пример: копирование в буфер обмена без отображения ввода

Приведенный выше простой пример отлично работает, если на экране виден элемент textarea или input.

В некоторых случаях вы можете скопировать текст в буфер обмена без отображения элемента input/textarea. Это один из примеров способа обойти это (в основном вставка элемента, копирование в буфер обмена, удаление элемента):

Протестировано с Google Chrome 44, Firefox 42.0a1 и Internet Explorer 11.0.8600.17814.

function copyTextToClipboard(text) {
  var textArea = document.createElement("textarea");

  //
  // *** This styling is an extra step which is likely not required. ***
  //
  // Why is it here? To ensure:
  // 1. the element is able to have focus and selection.
  // 2. if element was to flash render it has minimal visual impact.
  // 3. less flakyness with selection and copying which **might** occur if
  //    the textarea element is not visible.
  //
  // The likelihood is the element won't even render, not even a
  // flash, so some of these are just precautions. However in
  // Internet Explorer the element is visible whilst the popup
  // box asking the user for permission for the web page to
  // copy to the clipboard.
  //

  // Place in top-left corner of screen regardless of scroll position.
  textArea.style.position = 'fixed';
  textArea.style.top = 0;
  textArea.style.left = 0;

  // Ensure it has a small width and height. Setting to 1px / 1em
  // doesn't work as this gives a negative w/h on some browsers.
  textArea.style.width = '2em';
  textArea.style.height = '2em';

  // We don't need padding, reducing the size if it does flash render.
  textArea.style.padding = 0;

  // Clean up any borders.
  textArea.style.border = 'none';
  textArea.style.outline = 'none';
  textArea.style.boxShadow = 'none';

  // Avoid flash of white box if rendered for any reason.
  textArea.style.background = 'transparent';


  textArea.value = text;

  document.body.appendChild(textArea);
  textArea.focus();
  textArea.select();

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

  document.body.removeChild(textArea);
}


var copyBobBtn = document.querySelector('.js-copy-bob-btn'),
  copyJaneBtn = document.querySelector('.js-copy-jane-btn');

copyBobBtn.addEventListener('click', function(event) {
  copyTextToClipboard('Bob');
});


copyJaneBtn.addEventListener('click', function(event) {
  copyTextToClipboard('Jane');
});
<div style="display:inline-block; vertical-align:top;">
  <button class="js-copy-bob-btn">Set clipboard to BOB</button><br /><br />
  <button class="js-copy-jane-btn">Set clipboard to JANE</button>
</div>
<div style="display:inline-block;">
  <textarea class="js-test-textarea" cols="35" rows="4">Try pasting into here to see what you have on your clipboard:

  </textarea>
</div>

Дополнительные примечания

Работает только в том случае, если пользователь выполняет действие

Все вызовы document.execCommand('copy') должны выполняться как прямой результат действий пользователя, например, щелкните обработчик события. Это мера, позволяющая избежать путаницы с буфером обмена пользователя, когда он этого не ожидает.

Смотрите сообщение для разработчиков Google здесь для получения дополнительной информации.

API буфера обмена

Обратите внимание, что полный проект спецификации API буфера обмена можно найти здесь: https://w3c.github.io/clipboard-apis/

Это поддерживается?

  • document.queryCommandSupported('copy') должен вернуть true, если команда «поддерживается браузером».
  • и document.queryCommandEnabled('copy') возвращают true, если document.execCommand('copy') будет успешным, если вызывается сейчас. Проверка того, что команда была вызвана из потока, инициированного пользователем, и выполнены ли другие требования.

Однако в качестве примера проблем совместимости браузера Google Chrome с ~ апреля по октябрь 2015 года возвращал true из document.queryCommandSupported('copy') только если команда была вызвана из потока, инициированного пользователем.

Обратите внимание на детали совместимости ниже.

Сведения о совместимости браузера

В то время как простой вызов document.execCommand('copy'), заключенный в блок try/catch, вызываемый в результате щелчка пользователя, обеспечит вам наибольшую совместимость, использование следующих условий имеет некоторые условия:

Любой вызов document.execCommand, document.queryCommandSupported или document.queryCommandEnabled должен быть заключен в блок try/catch.

Различные реализации браузера и версии браузера выдают различные типы исключений при вызове вместо возврата false.

Различные реализации браузеров все еще находятся в процессе разработки, а Clipboard API все еще находится в стадии разработки, поэтому не забудьте провести тестирование.

1789
Dean Taylor

Автоматическое копирование в буфер обмена может быть опасным, поэтому большинство браузеров (кроме IE) делают это очень сложно. Лично я использую следующий простой трюк:

function copyToClipboard(text) {
  window.Prompt("Copy to clipboard: Ctrl+C, Enter", text);
}

Пользователю предоставляется поле "Запрос", в котором текст для копирования уже выделен. Теперь достаточно нажать Ctrl+C а также Enter (закрыть коробку) - и вуаля!

Теперь операция копирования в буфер обмена БЕЗОПАСНА, потому что пользователь делает это вручную (но довольно просто). Конечно, работает во всех браузерах.

<button id="demo" onclick="copyToClipboard(document.getElementById('demo').innerHTML)">This is what I want to copy</button>

<script>
  function copyToClipboard(text) {
    window.Prompt("Copy to clipboard: Ctrl+C, Enter", text);
  }
</script>
1228
Jarek Milewski

Следующий подход работает в Chrome, Firefox, Internet Explorer и Edge, а также в последних версиях Safari (поддержка копирования была добавлена ​​в версии 10, выпущенной в октябре 2016 года).

  • Создайте текстовую область и установите для ее содержимого текст, который вы хотите скопировать в буфер обмена.
  • Добавьте текстовое поле к DOM.
  • Выделите текст в текстовой области.
  • Вызовите document.execCommand («копировать»)
  • Удалить текстовую область из дома.

Примечание: вы не увидите текстовое поле, так как оно добавляется и удаляется в рамках одного и того же синхронного вызова кода Javascript.

Некоторые вещи, на которые стоит обратить внимание, если вы реализуете это самостоятельно:

  • По соображениям безопасности это можно вызвать только из обработчика событий, такого как щелчок (так же, как при открытии окон).
  • IE покажет диалоговое окно с разрешениями при первом обновлении буфера обмена.
  • IE и Edge будут прокручиваться, когда текстовая область сфокусирована.
  • execCommand () может выдавать в некоторых случаях.
  • Новые строки и вкладки могут быть проглочены, если вы не используете текстовую область. (В большинстве статей рекомендуется использовать div)
  • Текстовая область будет видна, пока отображается диалоговое окно IE, вам нужно либо скрыть его, либо использовать специфический IE api clipboardData.
  • В IE системные администраторы могут отключить API буфера обмена.

Приведенная ниже функция должна обрабатывать все следующие проблемы как можно более чисто. Пожалуйста, оставьте комментарий, если вы обнаружите какие-либо проблемы или у вас есть предложения по улучшению.

// Copies a string to the clipboard. Must be called from within an 
// event handler such as click. May return false if it failed, but
// this is not always possible. Browser support for Chrome 43+, 
// Firefox 42+, Safari 10+, Edge and IE 10+.
// IE: The clipboard feature may be disabled by an administrator. By
// default a Prompt is shown the first time the clipboard is 
// used (per session).
function copyToClipboard(text) {
    if (window.clipboardData && window.clipboardData.setData) {
        // IE specific code path to prevent textarea being shown while dialog is visible.
        return clipboardData.setData("Text", text); 

    } else if (document.queryCommandSupported && document.queryCommandSupported("copy")) {
        var textarea = document.createElement("textarea");
        textarea.textContent = text;
        textarea.style.position = "fixed";  // Prevent scrolling to bottom of page in MS Edge.
        document.body.appendChild(textarea);
        textarea.select();
        try {
            return document.execCommand("copy");  // Security exception may be thrown by some browsers.
        } catch (ex) {
            console.warn("Copy to clipboard failed.", ex);
            return false;
        } finally {
            document.body.removeChild(textarea);
        }
    }
}

https://jsfiddle.net/fx6a6n6x/

221
Greg Lowe

Если вы хотите действительно простое решение (занимает меньше 5 минут для интеграции) и хорошо выглядят прямо из коробки, тогда Clippy - хорошая альтернатива некоторым из более сложных решений.

Он был написан соучредителем GitHub. Пример встроенного кода Flash ниже:

<object
   classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
   width="110"
   height="14"
   id="clippy">
  <param name="movie" value="/flash/clippy.swf"/>
  <param name="allowScriptAccess" value="always"/>
  <param name="quality" value="high"/>
  <param name="scale" value="noscale"/>
  <param NAME="FlashVars" value="text=#{text}"/>
  <param name="bgcolor" value="#{bgcolor}"/>
  <embed
     src="/flash/clippy.swf"
     width="110"
     height="14"
     name="clippy"
     quality="high"
     allowScriptAccess="always"
     type="application/x-shockwave-flash"
     pluginspage="http://www.macromedia.com/go/getflashplayer"
     FlashVars="text=#{text}"
     bgcolor="#{bgcolor}"/>
</object>

Не забудьте заменить #{text} текстом, который вам нужно скопировать, а #{bgcolor} цветом.

93
Brent Matzelle

Чтение и изменение буфера обмена с веб-страницы вызывает проблемы безопасности и конфиденциальности. Однако в Internet Explorer это можно сделать. Я нашел этот пример фрагмента :

    <script type="text/javascript">
        function select_all(obj) {
            var text_val=eval(obj);
            text_val.focus();
            text_val.select();
            r = text_val.createTextRange();
            if (!r.execCommand) return; // feature detection
            r.execCommand('copy');
        }
    </script>
    <input value="http://www.sajithmr.com"
     onclick="select_all(this)" name="url" type="text" />

80
bandi

Я недавно написал технический пост в блоге об этой самой проблеме (я работаю в Lucidchart, и мы недавно сделали капитальный ремонт нашего буфера обмена).

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

var isIe = (navigator.userAgent.toLowerCase().indexOf("msie") != -1 
           || navigator.userAgent.toLowerCase().indexOf("trident") != -1);

document.addEventListener('copy', function(e) {
    var textToPutOnClipboard = "This is some text";
    if (isIe) {
        window.clipboardData.setData('Text', textToPutOnClipboard);    
    } else {
        e.clipboardData.setData('text/plain', textToPutOnClipboard);
    }
    e.preventDefault();
});

Поместить текст в буфер обмена не во время системного копирования намного сложнее. Похоже, что некоторые из этих других ответов ссылаются на способы сделать это через Flash, который является единственным кросс-браузерным способом сделать это (насколько я понимаю).

Кроме этого, есть несколько вариантов для каждого браузера.

Это самый простой в IE, где вы можете получить доступ к объекту clipboardData в любое время из JavaScript через:

window.clipboardData

(Однако при попытке сделать это вне системного события вырезания, копирования или вставки IE предложит пользователю предоставить разрешение для буфера обмена веб-приложения.)

В Chrome вы можете создать расширение Chrome, которое даст вам разрешения для буфера обмена (это то, что мы делаем для Lucidchart). Тогда для пользователей с установленным расширением вам просто нужно самостоятельно запустить системное событие:

document.execCommand('copy');

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

67
Richard Shurtz

Вот мой взгляд на это ..

function copy(text) {
    var input = document.createElement('input');
    input.setAttribute('value', text);
    document.body.appendChild(input);
    input.select();
    var result = document.execCommand('copy');
    document.body.removeChild(input)
    return result;
 }
44
nikksan

clipboard.js - небольшая, не Flash, утилита, которая позволяет копировать текстовые или HTML-данные в буфер обмена. Это очень легко использовать, просто включите .js и используйте что-то вроде этого:

<button id='markup-copy'>Copy Button</button>

<script>
document.getElementById('markup-copy').addEventListener('click', function() {
  clipboard.copy({
    'text/plain': 'Markup text. Paste me into a rich text editor.',
    'text/html': '<i>here</i> is some <b>rich text</b>'
  }).then(
    function(){console.log('success'); },
    function(err){console.log('failure', err);
  });

});
</script>

clipboard.js также находится на GitHub .

Примечание: Это устарело. Перейдите на здесь .

44
a coder

ZeroClipboard - лучшее кросс-браузерное решение, которое я нашел:

<div id="copy" data-clipboard-text="Copy Me!">Click to copy</div>    
<script src="ZeroClipboard.js"></script>
<script>
  var clip = new ZeroClipboard( document.getElementById('copy') );
</script>

Если вам нужна поддержка не-flash для iOS, просто добавьте запасной вариант:

clip.on( 'noflash', function ( client, args ) {
    $("#copy").click(function(){            
        var txt = $(this).attr('data-clipboard-text');
        Prompt ("Copy link, then click OK.", txt);
    });
});  

http://zeroclipboard.org/

https://github.com/zeroclipboard/ZeroClipboard

34
Justin

В одном из проектов, над которым я работал, плагин jQuery для копирования в буфер обмена, использующий библиотеку Zero Clipboard .

Он проще в использовании, чем нативный плагин Zero Clipboard, если вы большой пользователь jQuery.

25
SteamDev

Я нашел следующее решение:

Обработчик нажатия клавиш создает тег «pre». Мы устанавливаем содержимое для копирования в этот тег, затем выбираем этот тег и возвращаем true в обработчике. Это вызывает стандартный обработчик хрома и копирует выделенный текст.

И если вам нужно, вы можете установить тайм-аут для функции для восстановления предыдущего выбора. Моя реализация на Mootools:

   function EnybyClipboard() {
     this.saveSelection = false;
     this.callback = false;
     this.pastedText = false;

     this.restoreSelection = function() {
       if (this.saveSelection) {
         window.getSelection().removeAllRanges();
         for (var i = 0; i < this.saveSelection.length; i++) {
           window.getSelection().addRange(this.saveSelection[i]);
         }
         this.saveSelection = false;
       }
     };

     this.copyText = function(text) {
       var div = $('special_copy');
       if (!div) {
         div = new Element('pre', {
           'id': 'special_copy',
           'style': 'opacity: 0;position: absolute;top: -10000px;right: 0;'
         });
         div.injectInside(document.body);
       }
       div.set('text', text);
       if (document.createRange) {
         var rng = document.createRange();
         rng.selectNodeContents(div);
         this.saveSelection = [];
         var selection = window.getSelection();
         for (var i = 0; i < selection.rangeCount; i++) {
           this.saveSelection[i] = selection.getRangeAt(i);
         }
         window.getSelection().removeAllRanges();
         window.getSelection().addRange(rng);
         setTimeout(this.restoreSelection.bind(this), 100);
       } else return alert('Copy not work. :(');
     };

     this.getPastedText = function() {
       if (!this.pastedText) alert('Nothing to paste. :(');
       return this.pastedText;
     };

     this.pasteText = function(callback) {
       var div = $('special_paste');
       if (!div) {
         div = new Element('textarea', {
           'id': 'special_paste',
           'style': 'opacity: 0;position: absolute;top: -10000px;right: 0;'
         });
         div.injectInside(document.body);
         div.addEvent('keyup', function() {
           if (this.callback) {
             this.pastedText = $('special_paste').get('value');
             this.callback.call(null, this.pastedText);
             this.callback = false;
             this.pastedText = false;
             setTimeout(this.restoreSelection.bind(this), 100);
           }
         }.bind(this));
       }
       div.set('value', '');
       if (document.createRange) {
         var rng = document.createRange();
         rng.selectNodeContents(div);
         this.saveSelection = [];
         var selection = window.getSelection();
         for (var i = 0; i < selection.rangeCount; i++) {
           this.saveSelection[i] = selection.getRangeAt(i);
         }
         window.getSelection().removeAllRanges();
         window.getSelection().addRange(rng);
         div.focus();
         this.callback = callback;
       } else return alert('Fail to paste. :(');
     };
   }

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

enyby_clip = new EnybyClipboard(); //init 

enyby_clip.copyText('some_text'); // place this in CTRL+C handler and return true;

enyby_clip.pasteText(function callback(pasted_text) {
        alert(pasted_text);
}); // place this in CTRL+V handler and return true;

При вставке он создает текстовую область и работает так же.

PS может быть это решение может быть использовано для создания полностью кросс-браузерного решения без флеш Работает в FF и Chrome.

21
Enyby

Гиш, не уверен, почему никто еще не указал на это.

В 2018 году, ребята, вот как вы можете это сделать:

async copySomething(text?) {
  try {
    const toCopy = text || location.href;
    await navigator.clipboard.writeText(toCopy);
    console.log('Text or Page URL copied');
  } catch (err) {
    console.error('Failed to copy: ', err);
  }
}

Используется в моем коде Angular 6+ примерно так:

<button mat-menu-item (click)="copySomething()">
    <span>Copy link</span>
</button>

Если я передаю строку, она копируется. Если ничего, копирует URL страницы.

Можно сделать еще больше гимнастики для буфера обмена. Смотрите больше информации здесь:

https://developers.google.com/web/updates/2018/03/clipboardapi

21
Rexford

Другие методы будут копировать обычный текст в буфер обмена. Чтобы скопировать HTML (т.е. вы можете вставить результаты в редактор WSIWYG), вы можете сделать следующее в IE ТОЛЬКО . Это принципиально отличается от других методов, поскольку браузер фактически визуально выбирает контент.

// create an editable DIV and append the HTML content you want copied
var editableDiv = document.createElement("div");
with (editableDiv) {
    contentEditable = true;
}     
editableDiv.appendChild(someContentElement);          

// select the editable content and copy it to the clipboard
var r = document.body.createTextRange();
r.moveToElementText(editableDiv);
r.select();  
r.execCommand("Copy");

// deselect, so the browser doesn't leave the element visibly selected
r.moveToElementText(someHiddenDiv);
r.select();   
19
Chase Seibert

Я использую это очень успешно ( без jquery или любой другой фреймворк).

function copyToClp(txt){
    txt = document.createTextNode(txt);
    var m = document;
    var w = window;
    var b = m.body;
    b.appendChild(txt);
    if (b.createTextRange) {
        var d = b.createTextRange();
        d.moveToElementText(txt);
        d.select();
        m.execCommand('copy');
    } else {
        var d = m.createRange();
        var g = w.getSelection;
        d.selectNodeContents(txt);
        g().removeAllRanges();
        g().addRange(d);
        m.execCommand('copy');
        g().removeAllRanges();
    }
    txt.remove();
} 

Предупреждение

Вкладки преобразуются в пробелы (по крайней мере, в Chrome).

18
Peter Rader

С недавних пор Chrome 42+ и Firefox 41+ теперь поддерживают команду document.execCommand ('copy'). Поэтому я создал несколько функций для кросс-браузерного копирования в буфер обмена, используя комбинацию старый ответ Тима Дауна и ответ Google Developer :

function selectElementContents(el) {
    // Copy textarea, pre, div, etc.
    if (document.body.createTextRange) {
        // IE 
        var textRange = document.body.createTextRange();
        textRange.moveToElementText(el);
        textRange.select();
        textRange.execCommand("Copy");
    } else if (window.getSelection && document.createRange) {
        // non-IE
        var range = document.createRange();
        range.selectNodeContents(el);
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
        try {
            var successful = document.execCommand('copy');
            var msg = successful ? 'successful' : 'unsuccessful';
            console.log('Copy command was ' + msg);
        } catch (err) {
            console.log('Oops, unable to copy');
        }
    }
} // end function selectElementContents(el) 

function make_copy_button(el) {
    var copy_btn = document.createElement('input');
    copy_btn.type = "button";
    el.parentNode.insertBefore(copy_btn, el.nextSibling);
    copy_btn.onclick = function() {
        selectElementContents(el);
    };

    if (document.queryCommandSupported("copy") || parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2]) >= 42) {
        // Copy works with IE 4+, Chrome 42+, Firefox 41+, Opera 29+
        copy_btn.value = "Copy to Clipboard";
    } else {
        // Select only for Safari and older Chrome, Firefox and Opera
        copy_btn.value = "Select All (then press CTRL+C to Copy)";
    }
}
/* Note: document.queryCommandSupported("copy") should return "true" on browsers that support copy
	but there was a bug in Chrome versions 42 to 47 that makes it return "false".  So in those
	versions of Chrome feature detection does not work!
	See https://code.google.com/p/chromium/issues/detail?id=476508
*/

make_copy_button(document.getElementById("markup"));
<pre id="markup">
  Text that can be copied or selected with cross browser support.
</pre>

18
Jeff Baker

  <!DOCTYPE html>

  <style>
    #t {
      width: 1px
      height: 1px
      border: none
    }
    #t:focus {
      outline: none
    }
  </style>

  <script>
    function copy(text) {
      var t = document.getElementById('t')
      t.innerHTML = text
      t.select()
      try {
        var successful = document.execCommand('copy')
        var msg = successful ? 'successfully' : 'unsuccessfully'
        console.log('text coppied ' + msg)
      } catch (err) {
        console.log('Unable to copy text')
      }
      t.innerHTML = ''
    }
  </script>

  <textarea id=t></textarea>

  <button onclick="copy('hello world')">
    Click me
  </button>

12
Samuel Tees

Начиная с Flash 10, вы можете копировать в буфер обмена только в том случае, если действие происходит в результате взаимодействия пользователя с объектом Flash. ( Читать соответствующий раздел из объявления Adobe Flash 10 )

Решение состоит в том, чтобы чрезмерно использовать Flash-объект над кнопкой «Копировать» или любым другим элементом, который инициирует копирование. Zero Clipboard в настоящее время является лучшей библиотекой с этой реализацией. Опытные разработчики Flash могут просто захотеть создать свою собственную библиотеку.

12
matthuhiggins

Я нашел следующее решение:

У меня есть текст в скрытом входе. Поскольку setSelectionRange не работает со скрытыми вводами, я временно изменил тип на текст, скопировал текст, а затем снова сделал его скрытым. Если вы хотите скопировать текст из элемента, вы можете передать его в функцию и сохранить его содержимое в целевой переменной.

    jQuery('#copy').on('click', function () {
        copyToClipboard();
    });

    function copyToClipboard() {
        var target = jQuery('#hidden_text');

        // make it visible, so can be focused
        target.attr('type', 'text');
        target.focus();
        // select all the text
        target[0].setSelectionRange(0, target.val().length);

        // copy the selection
        var succeed;
        try {
            succeed = document.execCommand("copy");
        } catch (e) {
            succeed = false;
        }

        // hide input again
        target.attr('type', 'hidden');

        return succeed;
    }
11
Vassilis Pallas

Копировать текст из HTML-ввода в буфер обмена

 
 function myFunction() {
  /* Get the text field */
   var copyText = document.getElementById("myInput");
 
   /* Select the text field */
   copyText.select();

   /* Copy the text inside the text field */
   document.execCommand("Copy");
 
   /* Alert the copied text */
   alert("Copied the text: " + copyText.value);
 }
 
 
 <!-- The text field -->
 <input type="text" value="Hello Friend" id="myInput">
 
 <!-- The button used to copy the text -->
<button onclick="myFunction()">Copy text</button>
 

Примечание: _ ​​Метод document.execCommand() не поддерживается в IE9 и более ранних версиях.

Source: W3Schools - Копировать текст в буфер обмена

10
Alexandru Sirbu

Я собрал то, что считаю лучшим.

  • Использует cssText, чтобы избежать исключений в IE, в отличие от стиля напрямую.
  • Восстанавливает выбор, если он был
  • Устанавливает только чтение, чтобы клавиатура не появлялась на мобильных устройствах
  • Есть обходной путь для iOS, так что он на самом деле работает, как обычно, блокирует execCommand.

Вот:

const copyToClipboard = (function initClipboardText() {
  const textarea = document.createElement('textarea');

  // Move it off screen.
  textarea.style.cssText = 'position: absolute; left: -99999em';

  // Set to readonly to prevent mobile devices opening a keyboard when
  // text is .select()'ed.
  textarea.setAttribute('readonly', true);

  document.body.appendChild(textarea);

  return function setClipboardText(text) {
    textarea.value = text;

    // Check if there is any content selected previously.
    const selected = document.getSelection().rangeCount > 0 ?
      document.getSelection().getRangeAt(0) : false;

    // iOS Safari blocks programmtic execCommand copying normally, without this hack.
    // https://stackoverflow.com/questions/34045777/copy-to-clipboard-using-javascript-in-ios
    if (navigator.userAgent.match(/ipad|iPod|iphone/i)) {
      const editable = textarea.contentEditable;
      textarea.contentEditable = true;
      const range = document.createRange();
      range.selectNodeContents(textarea);
      const sel = window.getSelection();
      sel.removeAllRanges();
      sel.addRange(range);
      textarea.setSelectionRange(0, 999999);
      textarea.contentEditable = editable;
    } else {
      textarea.select();
    }

    try {
      const result = document.execCommand('copy');

      // Restore previous selection.
      if (selected) {
        document.getSelection().removeAllRanges();
        document.getSelection().addRange(selected);
      }

      return result;
    } catch (err) {
      return false;
    }
  };
})();
10
Dominic

В браузерах, отличных от IE, вам нужно использовать небольшой flash-объект для работы с буфером обмена, например,.

9
Quog

У меня была такая же проблема при создании пользовательского редактирования сетки (что-то вроде Excel) и совместимости с Excel. Мне пришлось поддерживать выбор нескольких ячеек, копирование и вставку.

Решение: создайте текстовую область, в которую вы будете вставлять данные для копирования пользователем (для меня, когда пользователь выбирает ячейки), установите фокус на нем (например, когда пользователь нажимает Ctrl) и выделите весь текст.

Итак, когда пользователь нажал Ctrl + C он/она получает скопированные клетки, которые он/она выбрал. После тестирования просто изменил размер текстовой области до одного пикселя (я не проверял, будет ли он работать на дисплее: нет). Он хорошо работает во всех браузерах и прозрачен для пользователя.

Вставка - вы можете сделать то же самое (отличается от цели) - сосредоточьтесь на textarea и ловите события вставки, используя onpaste (в моем проекте я использую textareas в ячейках для редактирования).

Я не могу вставить пример (коммерческий проект), но вы поняли идею.

8
xiniu

Я использовал clipboard.js

мы можем получить это на нпм

npm install clipboard --save

а также на беседке

bower install clipboard --save

Использование и примеры на https://zenorocha.github.io/clipboard.js/

7
CodecPM

Уже много ответов, но мне нравится добавлять один (jQuery). Работает как брелок в любом браузере, в том числе и в мобильном (т.е. запрашивает безопасность, но когда вы принимаете его, он просто отлично работает).

function appCopyToClipBoard( sText )
{
 var oText = false,
     bResult = false;
 try
 {
  oText = document.createElement("textarea");
  $(oText).addClass('clipboardCopier').val(sText).insertAfter('body').focus();
  oText.select();
  document.execCommand("Copy");
  bResult = true;
 } catch(e) {}

 $(oText).remove();
 return bResult;
}

В вашем коде:

if( !appCopyToClipBoard( 'Hai there! This is copied to the clipboard.' ))
 { alert('Sorry, copy to clipboard failed.'); }
7
Codebeat

Это расширение ответа @ Chase с тем преимуществом, что оно будет работать для элементов IMAGE и TABLE, а не только для DIV в IE9.

if (document.createRange) {
    // IE9 and modern browsers
    var r = document.createRange();
    r.setStartBefore(to_copy);
    r.setEndAfter(to_copy);
    r.selectNode(to_copy);
    var sel = window.getSelection();
    sel.addRange(r);
    document.execCommand('Copy');  // does nothing on FF
} else {
    // IE 8 and earlier.  This stuff won't work on IE9.
    // (unless forced into a backward compatibility mode,
    // or selecting plain divs, not img or table). 
    var r = document.body.createTextRange();
    r.moveToElementText(to_copy);
    r.select()
    r.execCommand('Copy');
}
6
Oliver Bock

Это была единственная вещь, которую я когда-либо получал, после того, как искал разные способы поиска по всему интернету. Это грязная тема. Множество решений размещено по всему миру, и большинство из них НЕ работают. Это сработало для меня:

ПРИМЕЧАНИЕ. Этот код будет работать только в том случае, если он выполняется как прямой синхронный код с методом, похожим на метод onClick. Если вы вызываете асинхронный ответ на ajax или любым другим асинхронным способом, он не будет работать

copyToClipboard(text) {
    var copyText = document.createElement("input");
    copyText.type = "text";
    document.body.appendChild(copyText);
    copyText.style = "display: inline; width: 1px;";
    copyText.value = text;
    copyText.focus();
    document.execCommand("SelectAll");
    document.execCommand("Copy");
    copyText.remove();
}

Я действительно понимаю, что этот код будет показывать компонент шириной 1px на экране в течение миллисекунды, но решил не беспокоиться об этом, к чему другие могут обратиться в случае реальной проблемы.

5
user2080225

Кажется, я неправильно понял вопрос, но для справки вы можете извлечь диапазон DOM (не для буфера обмена; совместим со всеми современными браузерами) и объединить его с событиями oncopy, onpaste и onbeforepaste, чтобы получить поведение буфера обмена. Вот код для достижения этого: 

function clipBoard(sCommand) {
  var oRange=contentDocument.createRange();
  oRange.setStart(startNode, startOffset);
  oRange.setEnd(endNode, endOffset);
/* This is where the actual selection happens.
in the above, startNode and endNode are dom nodes defining the beginning 
and end of the "selection" respectively. startOffset and endOffset are 
constants that are defined as follows:

END_TO_END: 2
END_TO_START: 3
NODE_AFTER: 1
NODE_BEFORE: 0
NODE_BEFORE_AND_AFTER: 2
NODE_INSIDE: 3
START_TO_END: 1
START_TO_START: 0

and would be used like oRange.START_TO_END */
      switch(sCommand) {
    case "cut":
          this.oFragment=oRange.extractContents();
      oRange.collapse();
      break;
    case "copy":
      this.oFragment=oRange.cloneContents();
      break;
    case "paste":
      oRange.deleteContents();
      var cloneFragment=this.oFragment.cloneNode(true)
      oRange.insertNode(cloneFragment);
      oRange.collapse();
      break;
  }
}
5
mrBorna

Это что-то вроде комбинации между другими ответами.

var copyToClipboard = function(textToCopy){
    $("body")
        .append($('<input type="text" name="fname" class="textToCopyInput"/>' )
        .val(textToCopy))
        .find(".textToCopyInput")
        .select();
      try {
        var successful = document.execCommand('copy');
        var msg = successful ? 'successful' : 'unsuccessful';
        alert('Text copied to clipboard!');
      } catch (err) {
          window.Prompt("To copy the text to clipboard: Ctrl+C, Enter", textToCopy);
      }
     $(".textToCopyInput").remove();
}

Он использует jQuery, но это, конечно, не обязательно. Вы можете изменить это, если хотите. Я просто имел в своем распоряжении jQuery. Вы также можете добавить немного CSS, чтобы убедиться, что ввод не отображается. Например что-то вроде:

.textToCopyInput{opacity: 0; position: absolute;}

Или, конечно, вы могли бы также сделать некоторые встроенные стили

.append($('<input type="text" name="fname" style="opacity: 0;  position: absolute;" class="textToCopyInput"/>' )
5
Bart Burg

Виноват. Это работает только в IE.

Вот еще один способ скопировать текст:

<p>
    <a onclick="window.clipboardData.setData('text', document.getElementById('Test').innerText);">Copy</a>
</p>
5
dvallejo

Чтобы скопировать выделенный текст («Текст для копирования») в буфер обмена, создайте Bookmarklet (закладка браузера, которая выполняет Javsacript) и выполните его (щелкните по нему) . Он создаст временную текстовую область.

Код от Github:

https://Gist.github.com/stefanmaric/2abf96c740191cda3bc7a8b0fc905a7d

(function (text) {
  var node = document.createElement('textarea');
  var selection = document.getSelection();

  node.textContent = text;
  document.body.appendChild(node);

  selection.removeAllRanges();
  node.select();
  document.execCommand('copy');

  selection.removeAllRanges();
  document.body.removeChild(node);
})('Text To Copy');
5
Mau

Мне пришлось скопировать текст со страниц без ввода (текст внутри любого тега div/span) со страницы и придумать следующий код. Единственная хитрость заключается в том, чтобы иметь скрытое поле, но, как тип TEXT, не будет работать со скрытым типом. 

    function copyToClipboard(sID) {
        var aField = document.getElementById("hiddenField");

        aField.hidden   = false;
        aField.value    = document.getElementById(sID).textContent;
        aField.select();
        document.execCommand("copy");
        alert("Following text has been copied to the clipboard.\n\n" + aField.value);
        aField.hidden = true;
    }

И в HTML добавить следующее

input type = "text" id = "hiddenField" style = "width: 5px; border: 0" /> ...

4
NewToIOS

Похоже, вы взяли код из кнопки Greasemonkey\JavaScript Copy to Clipboard или из оригинального фрагмента этого фрагмента ...

Этот код был для Greasemonkey, следовательно, unsafeWindow. И я предполагаю, что синтаксическая ошибка в IE происходит от ключевого слова const, которое относится к Firefox (замените его на var).

4
PhiLho

Насколько я знаю, это работает только в Internet Explorer.

См. Также Динамические инструменты - JavaScript Copy To Clipboard, но для этого требуется, чтобы пользователь сначала изменил конфигурацию, и даже тогда, похоже, она не работает.

4
Stormenet

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

Я предлагаю это: http://zeroclipboard.org/

3
sinister

Обновление 2015: в настоящее время есть способ использовать document.execCommand для работы с буфером обмена . clipboard.js предоставляет кросс-браузерный способ работы с буфером обмена ( поддержка браузера )

3
Yaroslav Yakovlev

Я собирался использовать clipboard.js, но у него нет мобильного решения (пока) ... поэтому я написал супер маленькую библиотеку:

https://github.com/ryanpcmcquen/cheval

Это позволит либо скопировать текст (Desktop/Android/Safari 10+), либо, по крайней мере, выделить текст (более старые версии iOS). Minified это чуть более 1 КБ. В настольном Safari (нажмите Ctrl + C, чтобы скопировать. Вам также не нужно писать JavaScript, чтобы использовать его.

3
ryanpcmcquen

В Chrome вы можете использовать copy('the text or variable etc') . Хотя это не кросс-браузер (и не работает во фрагменте? ), вы можете добавить его к другим кросс-браузерным ответам.

2
drzaus

@Jimbo, вот простой буфер обмена на основе Ajax/сессии для того же сайта.

Обратите внимание, что сеанс должен быть включен и действителен, и это решение работает для того же сайта. Я протестировал его на CodeIgniter, но столкнулся с проблемой сессии/Ajax, но это тоже решил эту проблему. Если вы не хотите играть с сессиями, используйте таблицу базы данных.

JavaScript/jQuery

<script type="text/javascript">
    $(document).ready(function() {

        $("#copy_btn_id").click(function(){

            $.post("<?php echo base_url();?>ajax/foo_copy/"+$(this).val(), null,
                function(data){
                    // Copied successfully
                }, "html"
            );
        });

        $("#paste_btn_id").click(function() {

           $.post("<?php echo base_url();?>ajax/foo_paste/", null,
               function(data) {
                   $('#paste_btn_id').val(data);
               }, "html"
           );
        });
    });
</script>

HTML контент

<input type='text' id='copy_btn_id' onclick='this.select();'  value='myvalue' />
<input type='text' id='paste_btn_id' value='' />

PHP код

<?php
    class Ajax extends CI_Controller {

        public function foo_copy($val){
            $this->session->set_userdata(array('clipboard_val' => $val));
        }

        public function foo_paste(){
            echo $this->session->userdata('clipboard_val');
            exit();
        }
    }
?>
2
Saad

В дополнение к обновленному ответу Дина Тейлора (июль 2015 г.) , я написал метод jQuery, похожий на его пример.

jsFiddle

/**
* Copies the current selected text to the SO clipboard
* This method must be called from an event to work with `execCommand()`
* @param {String} text Text to copy
* @param {Boolean} [fallback] Set to true shows a Prompt
* @return Boolean Returns `true` if the text was copied or the user clicked on accept (in Prompt), `false` otherwise
*/
var CopyToClipboard = function(text, fallback){
    var fb = function () {
        $t.remove();
        if (fallback !== undefined && fallback) {
            var fs = 'Please, copy the following text:';
            if (window.Prompt(fs, text) !== null) return true;
        }
        return false;
    };
    var $t = $('<textarea />');
    $t.val(text).css({
        width: '100px',
        height: '40px'
    }).appendTo('body');
    $t.select();
    try {
        if (document.execCommand('copy')) {
            $t.remove();
            return true;
        }
        fb();
    }
    catch (e) {
        fb();
    }
};
2
kosmos

Если вы читаете текст из буфера обмена в расширении Chrome с разрешением «clipboardRead», вы можете использовать следующий код:

function readTextFromClipboardInChromeExtension() {
    var ta = $('<textarea/>');
    $('body').append(ta);
    ta.focus();
    document.execCommand('paste');
    var text = ta.val();
    ta.blur();
    ta.remove();
    return text;
}
2
supNate

Используя функцию Javascript с использованием try/catch, вы можете даже лучше обрабатывать ошибки, выполняя это так:

 copyToClipboard() {
     let el = document.getElementById('Test').innerText
     el.focus(); // el.select();
     try {
         var successful = document.execCommand('copy');
         if (successful) {
             console.log('Copied Successfully! Do whatever you want next');
         } else {
             throw ('Unable to copy');
         }
     } catch (err) {
         console.warn('Oops, Something went wrong ', err);
     }
 }
2
Adeel Imran

Если скопированная ссылка должна быть вставлена ​​на тот же сайт, то простое решение состоит в том, чтобы выделить текст перед нажатием простой кнопки копирования HTML, а затем при ее нажатии текстовое содержимое сохраняется в сеансе. И там, где его нужно вставить, есть кнопка вставки. 

** Я знаю, это не постоянное и универсальное решение, но это что-то :)

2
Saad

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

window.copyToClipboard = function(text) {
  // IE specific
  if (window.clipboardData && window.clipboardData.setData) {
    return clipboardData.setData("Text", text);
  }

  // all other modern
  target = document.createElement("textarea");
  target.style.position = "absolute";
  target.style.left = "-9999px";
  target.style.top = "0";
  target.textContent = text;
  document.body.appendChild(target);
  target.focus();
  target.setSelectionRange(0, target.value.length);

  // copy the selection of fall back to Prompt
  try {
    document.execCommand("copy");
    target.remove();
    console.log('Copied to clipboard: "'+text+'"');
  } catch(e) {
    console.log("Can't copy string on this browser. Try to use Chrome, Firefox or Opera.")
    window.Prompt("Copy to clipboard: Ctrl+C, Enter", text);
  }
}

Проверьте это здесь https://jsfiddle.net/jv0avz65/

1
dux

После поиска решения, которое поддерживает Safari и другие браузеры (IE9 +),

Я использую так же, как Github: ZeroClipboard

Пример :

http://zeroclipboard.org/index-v1.x.html

HTML

<html>
  <body>
    <button id="copy-button" data-clipboard-text="Copy Me!" title="Click to copy me.">Copy to Clipboard</button>
    <script src="ZeroClipboard.js"></script>
    <script src="main.js"></script>
  </body>
</html>

JS

var client = new ZeroClipboard(document.getElementById("copy-button"));

client.on("ready", function (readyEvent) {
    // alert( "ZeroClipboard SWF is ready!" );

    client.on("aftercopy", function (event) {
        // `this` === `client`
        // `event.target` === the element that was clicked
        event.target.style.display = "none";
        alert("Copied text to clipboard: " + event.data["text/plain"]);
    });
});
1
user4912329

Просто добавляю мой к ответам. 

Это лучшее. Так много побед. 

var toClipboard = function(text) {
        var doc = document;

        // Create temp element
        var textarea = doc.createElement('textarea');
        textarea.style.position = 'absolute';
        textarea.style.opacity  = '0';
        textarea.textContent    = text;

        doc.body.appendChild(textarea);

        textarea.focus();
        textarea.setSelectionRange(0, textarea.value.length);

        // copy the selection
        var success;
        try {
                success = doc.execCommand("copy");
        } catch(e) {
                success = false;
        }

        textarea.remove();

        return success;
}
1
momomo

Это было единственное, что сработало для меня:

let textarea = document.createElement('textarea');
textarea.setAttribute('type', 'hidden');
textarea.textContent = 'the string you want to copy';
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
1
Alexander Mills

Я собрал решение, представленное здесь @ dean-taylor, вместе с другим кодом выбора/отмены выбора из другого места в плагине jQuery, доступном в NPM:

https://www.npmjs.com/package/jquery.text-select

Установка:

npm install --save jquery.text-select

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

<script>
    $(document).ready(function(){
        $("#selectMe").selectText(); // Hightlight / select the text
        $("#selectMe").selectText(false); // Clear the selection

        $("#copyMe").copyText(); // Copy text to clipboard
    });
</script>

Более подробную информацию о методах/событиях можно найти на странице реестра NPM выше.

0
Gruffy

Использование document.execCommand сделает всю работу за вас ...

Используя это, вы можете также сделать cut, copy и paste ...

Это одна из простых функций копирования буфера обмена, которая копирует все из входного текста ...

function copyInputText() {
  var copyText = document.querySelector("#input");
  copyText.select();
  document.execCommand("copy");
}

document.querySelector("#copy").addEventListener("click", copyInputText);
<input id="input" type="text" />
<button id="copy">Copy</button>

Для получения дополнительной информации посетите здесь

0
Alireza

Это можно сделать, просто используя комбинацию getElementbyId, Select (), blur () и команды copy.

Заметка

метод select () выделяет весь текст в элементе или элементе с текстовым полем. Это может не работать на кнопке

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

let copyText = document.getElementById('input-field');
copyText.select()
document.execCommand("copy");
copyReferal.blur()
document.getElementbyId('help-text').textContent = 'Copied'

Метод blur () удалит некрасиво выделенную часть вместо того, чтобы вы могли показать в красивом сообщении, что ваш контент был успешно скопирован

0
Nishant Singh

Вот элегантное решение для Angular 5.x +:

Составная часть:

import {
  ChangeDetectionStrategy,
  ChangeDetectorRef,
  Component,
  ElementRef,
  EventEmitter,
  Input,
  OnInit,
  Output,
  Renderer2,
  ViewChild
} from '@angular/core';

@Component({
  selector: 'copy-to-clipboard',
  templateUrl: './copy-to-clipboard.component.html',
  styleUrls: ['./copy-to-clipboard.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})

export class CopyToClipboardComponent implements OnInit {
  @ViewChild('input') input: ElementRef;
  @Input() size = 'md';
  @Input() theme = 'complement';
  @Input() content: string;
  @Output() copied: EventEmitter<string> = new EventEmitter<string>();
  @Output() error: EventEmitter<string> = new EventEmitter<string>();

  constructor(private renderer: Renderer2) {}

  ngOnInit() {}

  copyToClipboard() {

    const rootElement = this.renderer.selectRootElement(this.input.nativeElement);

    // iOS Safari blocks programmtic execCommand copying normally, without this hack.
    // https://stackoverflow.com/questions/34045777/copy-to-clipboard-using-javascript-in-ios
    if (navigator.userAgent.match(/ipad|iPod|iphone/i)) {

      this.renderer.setAttribute(this.input.nativeElement, 'contentEditable', 'true');

      const range = document.createRange();

      range.selectNodeContents(this.input.nativeElement);

      const sel = window.getSelection();

      sel.removeAllRanges();
      sel.addRange(range);

      rootElement.setSelectionRange(0, 999999);
    } else {
      rootElement.select();
    }

    try {
      document.execCommand('copy');
      this.copied.emit();
    } catch (err) {
      this.error.emit(err);
    }
  };
}

Шаблон:

<button class="btn btn-{{size}} btn-{{theme}}" type="button" (click)="copyToClipboard()">
  <ng-content></ng-content>
</button>

<input #input class="hidden-input" [ngModel]="content">

Стили:

.hidden-input {
  position: fixed;
  top: 0;
  left: 0;
  width: 1px; 
  height: 1px;
  padding: 0;
  border: 0;
  box-shadow: none;
  outline: none;
  background: transparent;
}
0
Chrillewoodz

Вот мое решение

var codeElement = document.getElementsByClassName("testelm") && document.getElementsByClassName("testelm").length ? document.getElementsByClassName("testelm")[0] : "";
        if (codeElement != "") {
            var e = document.createRange();
            e.selectNodeContents(codeElement);
            var selection = window.getSelection();
            selection.removeAllRanges();
            selection.addRange(e);
            document.execCommand("Copy");
            selection.removeAllRanges();
        }
0
Adithya Sai