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

Ответ 1

обзор

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

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

Ответ 2

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

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

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

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

<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>

Ответ 3

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

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

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

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

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

Ответ 4

Если вы хотите действительно простое решение (занимает меньше 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} цветом.

Ответ 5

Чтение и изменение буфера обмена с веб-страницы вызывает проблемы безопасности и конфиденциальности. Однако в 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" />

Ответ 6

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

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

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 есть некоторые параметры, которые позволяют пользователям предоставлять разрешения определенным сайтам для доступа к буферу обмена, но я не пробовал ничего из этого лично.

Ответ 7

Вот мое занятие на этом...

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;
 }

Ответ 8

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.

Примечание. Это устарело. Мигрируй сюда.

Ответ 9

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>

Если вам нужна поддержка без флэш-памяти для iOS, вы просто добавляете fall-back:

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

Ответ 10

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

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

Ответ 11

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

В ручном манипуляторе создается тэг 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;

При вставке он создает textarea и работает одинаково.

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

Ответ 12

В последнее время Chrome 42+ и Firefox 41+ теперь поддерживают команду document.execCommand('copy'). Таким образом, я создал несколько функций для копирования кросс-браузера в буфер обмена с помощью комбинации старого ответа Tim Down и Ответ разработчика Google:

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>

Ответ 13

Geesh, не знаю, почему никто еще не указал на это.

В 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);
  }
}

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

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

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

Более гимнастика в буфер обмена может быть выполнена тоже. Подробнее см. Здесь:

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

Ответ 14

Другие методы скопируют обычный текст в буфер обмена. Чтобы скопировать 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();   

Ответ 15

Я использую это очень успешно (без 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).

Ответ 16

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

  • Использует 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) {
      console.error(err);
      return false;
    }
  };
})();

Использование: copyToClipboard('some text')

Ответ 17

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

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

Ответ 18

  <!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>

Ответ 19

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

У меня есть текст в скрытом входе. Поскольку 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;
    }

Ответ 20

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

 
 function myFunction() {
 /* Получить текстовое поле */
  var copyText = document.getElementById( "myInput" );
 
  /* Выберите текстовое поле */
  copyText.select();

  /* Скопируйте текст внутри текстового поля */
  document.execCommand( "Copy" );
 
  /* Оповещение скопированного текста */
  alert ( "Скопированный текст:" + copyText.value);
 }
 Код>
 
 <! - Текстовое поле - >
 < input type = "text" value = "Hello Friend" id =  "myInput"  >
 
 <! - Кнопка, используемая для копирования текста - >
< button onclick = "myFunction()" > Копировать текст </button>
 Код>

Ответ 22

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

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

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

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

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

Ответ 23

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

var copyToClipboard = function(textToCopy){
    $("body")
        .append($('<textarea 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($('<textarea name="fname" style="opacity: 0;  position: absolute;" class="textToCopyInput"/>' )

Ответ 24

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

Ответ 25

Это расширение ответа @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');
}

Ответ 26

Я нашел еще одно приятное решение LMCButton - небольшая анимационная кнопка перекрестного браузера. Одна функция JavaScript и кнопка swf. Простые варианты (подпись, пользовательский JavaScript).

Ссылка: Скопировать в буфер обмена LMCButton

Ответ 27

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

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

npm install clipboard --save

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

bower install clipboard --save

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

Ответ 28

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

Ответ 29

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

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

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

Ответ 30

ng-clip было самым простым решением для AngularJS.