Как мне скопировать в буфер обмена в JavaScript? - PullRequest
2958 голосов
/ 30 декабря 2008

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

Я пробовал:

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 получает доступ к буферу обмена пользователя?

Ответы [ 51 ]

9 голосов
/ 30 декабря 2008

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

8 голосов
/ 17 января 2011

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

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

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

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

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

7 голосов
/ 12 декабря 2016

Уже много ответов, но мне нравится добавлять один (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.'); }
6 голосов
/ 28 октября 2015

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

мы можем получить его по npm

npm install clipboard --save

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

bower install clipboard --save

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

6 голосов
/ 12 августа 2011

Это расширение ответа @ 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');
}
5 голосов
/ 16 августа 2011

Кажется, я неправильно понял вопрос, но для справки вы можете извлечь диапазон 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 голосов
/ 09 июля 2015

Это сочетание некоторых других ответов.

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 голосов
/ 14 сентября 2013

Мой плохой. Это работает только в IE.

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

<p>
    <a onclick="window.clipboardData.setData('text', document.getElementById('Test').innerText);">Copy</a>
</p>
5 голосов
/ 15 октября 2017

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

ПРИМЕЧАНИЕ. Этот код будет работать только в том случае, если он выполняется как прямой синхронный код с методом, подобным методу 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 голосов
/ 19 октября 2017

Чтобы скопировать выделенный текст («Текст для копирования») в буфер обмена, создайте 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');
...