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

2815 голосов | спросил Santiago Corredoira 30 TueEurope/Moscow2008-12-30T16:09:05+03:00Europe/Moscow12bEurope/MoscowTue, 30 Dec 2008 16:09:05 +0300 2008, 16:09:05

29 ответов


0

Обзор

Существует три основных 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. Переопределение события копирования
    • См. документацию по API буфера обмена в переопределении события копирования .
    • Позволяет изменять то, что появляется в буфере обмена, из любого события копирования, может включать другие форматы данных, кроме обычного текста.
    • Здесь не рассматривается, так как это не дает прямого ответа на вопрос.

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

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

Async + Fallback

Из-за уровня поддержки браузером нового API-интерфейса буфера обмена Async вы, вероятно, захотите использовать метод 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>

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

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 ( 'Copy')

Остальная часть этого поста посвящена нюансам и деталям 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 и IE 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 IE 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.

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

ответил Dean Taylor 12 J0000006Europe/Moscow 2015, 21:56:18
0

Автоматическое копирование в буфер обмена может быть опасным, поэтому большинство браузеров (кроме 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>
ответил Jarek Milewski 19 Maypm11 2011, 12:06:06
0

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

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

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

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

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

ответил Greg Lowe 26 42015vEurope/Moscow11bEurope/MoscowThu, 26 Nov 2015 03:03:49 +0300 2015, 03:03:49
0

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

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} с цветом.

ответил Brent Matzelle 17 +04002010-10-17T18:40:35+04:00312010bEurope/MoscowSun, 17 Oct 2010 18:40:35 +0400 2010, 18:40:35
0

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

ответил Richard Shurtz 3 WedEurope/Moscow2014-12-03T23:31:06+03:00Europe/Moscow12bEurope/MoscowWed, 03 Dec 2014 23:31:06 +0300 2014, 23:31:06
0

clipboard.js - это небольшая не флэш-утилита, которая позволяет копировать текстовые или 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

ответил a coder 11 PM00000060000003731 2015, 18:33:37
0

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

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;
 }
ответил nikksan 14 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowThu, 14 Sep 2017 12:20:33 +0300 2017, 12:20:33
0

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

ответил Justin 22 52013vEurope/Moscow11bEurope/MoscowFri, 22 Nov 2013 00:41:25 +0400 2013, 00:41:25
0

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

ответил SteamDev 4 Mayam11 2011, 02:17:01
0

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

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

И если вам нужно, вы можете установить тайм-аут для функции для восстановления предыдущего выбора. Моя реализация на 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.

ответил Enyby 5 J000000Thursday12 2012, 19:33:32
0

Другие методы копируют обычный текст в буфер обмена. Чтобы скопировать 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();   
ответил Chase Seibert 30 TueEurope/Moscow2008-12-30T17:33:38+03:00Europe/Moscow12bEurope/MoscowTue, 30 Dec 2008 17:33:38 +0300 2008, 17:33:38
0

С недавних пор Chrome 42+ и Firefox 41+ теперь поддерживает команду document.execCommand ('copy') . Поэтому я создал несколько функций для копирования между браузерами в буфер обмена, используя комбинацию старого ответа Тима Дауна и ответ разработчика 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>
ответил Jeff Baker 5 42015vEurope/Moscow11bEurope/MoscowThu, 05 Nov 2015 06:50:33 +0300 2015, 06:50:33
0

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

В 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

ответил Rexford 6 PM00000040000003931 2018, 16:42:39
0

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

ответил Peter Rader 1 J000000Sunday18 2018, 21:52:46
0

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

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

ответил matthuhiggins 17 MarpmWed, 17 Mar 2010 23:12:39 +03002010-03-17T23:12:39+03:0011 2010, 23:12:39
0

   <!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>
ответил Samuel Tees 13 J0000006Europe/Moscow 2017, 20:51:01
0

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

У меня есть текст в скрытом вводе. Поскольку 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;
    }
ответил Vassilis Pallas 18 Jpm1000000pmWed, 18 Jan 2017 13:57:02 +030017 2017, 13:57:02
0

Копировать текст из 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 и более ранних версиях.

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

ответил Alexandru Sirbu 26 Jam1000000amFri, 26 Jan 2018 01:42:01 +030018 2018, 01:42:01
0

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

  • Использует 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;
    }
  };
})();
ответил Dominic 25 J000000Tuesday17 2017, 18:51:33
0

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

ответил Quog 30 TueEurope/Moscow2008-12-30T16:38:51+03:00Europe/Moscow12bEurope/MoscowTue, 30 Dec 2008 16:38:51 +0300 2008, 16:38:51
0

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

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

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

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

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

ответил xiniu 17 Jpm1000000pmMon, 17 Jan 2011 20:09:45 +030011 2011, 20:09:45
0

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

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

npm install clipboard --save

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

bower install clipboard --save

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

ответил CodecPM 28 +03002015-10-28T14:17:06+03:00312015bEurope/MoscowWed, 28 Oct 2015 14:17:06 +0300 2015, 14:17:06
0

Уже много ответов, но мне нравится добавлять один (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.'); }
ответил Codebeat 12 MonEurope/Moscow2016-12-12T19:22:02+03:00Europe/Moscow12bEurope/MoscowMon, 12 Dec 2016 19:22:02 +0300 2016, 19:22:02
0

Это расширение ответа @ 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');
}
ответил Oliver Bock 12 PM000000120000003231 2011, 12:17:32
0

Кажется, я неправильно понял вопрос, но для справки вы можете извлечь диапазон 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;
  }
}
ответил mrBorna 16 PM000000110000004731 2011, 23:22:47
0

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

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

<p>
    <a onclick="window.clipboardData.setData('text', document.getElementById('Test').innerText);">Copy</a>
</p>
ответил dvallejo 14 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowSat, 14 Sep 2013 01:56:09 +0400 2013, 01:56:09
0

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

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"/>' )
ответил Bart Burg 9 J000000Thursday15 2015, 17:24:25
0

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

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

ответил 15 +03002017-10-15T02:15:10+03:00312017bEurope/MoscowSun, 15 Oct 2017 02:15:10 +0300 2017, 02:15:10
0

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

Код от Github:

https://gist.github.com/stefanmaric/2abf96c740191aa0

(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');

ответил Mauro 19 +03002017-10-19T05:33:37+03:00312017bEurope/MoscowThu, 19 Oct 2017 05:33:37 +0300 2017, 05:33:37

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132