Как лучше всего скопировать текст в буфер обмена (в нескольких браузерах)?
Я пытался:
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 не определен.
Хороший трюк без использования Вспышка: Как Trello получает доступ к буферу обмена пользователя?
Ничего особенного. Они могут сделать это сами, но я хочу предложить также возможность нажатия кнопки, не беспокоясь о выборе правильной части текста.
Это длинное сообщение в блоге содержит множество способов сделать это: Доступ к системному буферу обмена с помощью JavaScript - Святой Грааль?
Это дает браузеру неопределенное исключение в IE, а также в FF
Если мы можем поместить текст в буфер обмена пользователя, мы можем испортить его буфер обмена.
Это все еще не полностью поддерживается. Вы можете увидеть поддержку на Могу ли я использовать API буфера обмена? в котором подробно описывается поддержка Документ API буфера обмена W3C.
@Mike, вероятно, никогда не будет из-за последствий для безопасности.
Я создал простую в использовании библиотеку Angular ngxyz-c2c, если вам это нужно.
Лично я предпочитаю сторонних разработчиков, например clipboardjs. clipboardjs: clipboardjs.com vue-clipboard: zhuowenli.github.io/vue-clipboards v-буфер обмена: vuejsexamples.com/a-clipboard-library-with-vue-js



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Насколько я знаю, работает только в Internet Explorer.
См. Также Динамические инструменты - копирование JavaScript в буфер обмена, но он требует, чтобы пользователь сначала изменил конфигурацию, и даже тогда это не работает.
Это не мультибраузерность, как запрошено.
Чтение и изменение буфера обмена с веб-страницы вызывает проблемы с безопасностью и конфиденциальностью. Однако в 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" />Использование флэш-памяти для простой операции копирования кажется излишним, и я рад, что для этого есть чистый JS-способ. А поскольку мы находимся в корпоративной среде. IE в порядке. Спасибо, Банди!
Объясните, пожалуйста, что делает execCommand(\\’copy\\’);, если не копирует в буфер обмена для IE? @mrBorna
Не используйте if (!document.all), а if (!r.execCommand), чтобы никто другой не реализовал это! Document.all к этому не имеет никакого отношения.
Почему эти проблемы конфиденциальности никогда не возникали в течение десяти лет, когда люди использовали Flash для изменения буфера обмена? И если мы разрешаем только один способ (т.е. копирование, а не чтение его содержимого), как это вызывает беспокойство о конфиденциальности?
@MuhammadbinYusrat: является - это проблема UX, хотя и не проблема конфиденциальности. Представьте, что пользователь что-то скопировал и думает, что он знает, что находится в буфере обмена, затем просматривает ваш сайт, и внезапно в буфере обмена появляется то, о чем он не просил, и он потерял то, что скопировал в первую очередь.
В браузерах, отличных от Internet Explorer, вам нужно использовать небольшой объект Flash для управления буфером обмена, например
Сейчас это устарело ... ознакомьтесь с предложением GvS
Предложение от GvS использует флеш-ролик? Разве это не та же идея?
Другие методы скопируют простой текст в буфер обмена. Чтобы скопировать HTML (то есть вы можете вставить результаты в редактор WYSIWYG), вы можете сделать следующее в Internet Explorer Только. Этот метод принципиально отличается от других методов, поскольку браузер фактически выбирает контент визуально.
// 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();
см. более полное решение HTML здесь stackoverflow.com/questions/34191780/…
Похоже, вы взяли код из Greasemonkey \ Кнопка JavaScript "Копировать в буфер обмена" или исходного источника этого фрагмента ...
Этот код был для Greasemonkey, отсюда и unsafeWindow. И я предполагаю, что синтаксическая ошибка в Internet Explorer возникает из-за ключевого слова const, специфичного для Firefox (замените его на var).
Ключевое слово const характерно не для Firefox, а для конкретной версии JavaScript, которую не все браузеры реализуют должным образом.
@ProfK На момент написания (10 лет назад ...) const был реализован только в Firefox и не был официальным (насколько я помню). Сегодня, конечно, почти все существующие браузеры поддерживают его.
Начиная с Flash 10, вы можете копировать в буфер обмена только в том случае, если действие происходит от взаимодействия пользователя с объектом Flash. (Прочтите соответствующий раздел объявления Adobe Flash 10.)
Решение состоит в том, чтобы наложить Flash-объект над кнопкой «Копировать» или каким-либо другим элементом, инициирующим копирование. ZeroClipboard в настоящее время является лучшей библиотекой с этой реализацией. Опытные разработчики Flash могут просто захотеть создать свою собственную библиотеку.
Если вам нужно действительно простое решение (интеграция занимает менее 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} - цветом.
Для всех, кто заинтересован, проверьте, что Clippy используется на GitHub при копировании URL-адреса репозитория.
У меня была такая же проблема с созданием настраиваемого редактирования сетки из (что-то вроде Excel) и совместимостью с Excel. Мне пришлось поддерживать выбор нескольких ячеек, копирование и вставку.
Решение: создайте текстовое поле, в которое вы будете вставлять данные для копирования пользователем (для меня, когда пользователь выбирает ячейки), установите на нем фокус (например, когда пользователь нажимает Ctrl) и выделите весь текст.
Итак, когда пользователь нажимает Ctrl + C, он получает скопированные ячейки, которые он выбрал. После тестирования просто измените размер текстового поля до одного пикселя (я не проверял, будет ли оно работать на дисплее: нет). Он прекрасно работает во всех браузерах и прозрачен для пользователя.
Вставка - вы можете сделать то же самое (отличается от вашей цели) - сосредоточьтесь на текстовом поле и перехватите события вставки с помощью onpaste (в моем проекте я использую текстовые поля в ячейках для редактирования).
Я не могу вставить пример (коммерческий проект), но вы поняли.
Из одного из проектов, над которым я работал, плагина jQuery для копирования в буфер обмена, который использует библиотеку ZeroClipboard.
Его проще использовать, чем собственный плагин Zero Clipboard, если вы интенсивно пользуетесь jQuery.
jQuery не считается законным ответом на вопрос о JavaScript, поскольку он не только раздут, но и использует ненадежные проприетарные методы Microsoft JScript, такие как innerHTML, которые неправильно регистрируют DOM.
92 КБ на самом деле не так уж и много, он работает быстро, и вы можете использовать text() вместо innerHTML(), если хотите ..
@John: innerHTML уже давно поддерживает кроссбраузерность. Тот факт, что Microsoft изначально придумал эту идею, не делает ее ненадежной или несвободной. Также теперь наконец-то добавляется в официальную спецификацию (после того, как все основные производители браузеров уже добавили его поддержку ... вздох).
@John Вы жалуетесь на то, что jQuery недостаточно JavaScripty в ответе, использующем Flash;)
Есть много вещей, которые стандартизированы, но не должны. Если вы решите использовать код, который МОЖЕТ работать и НЕ МОЖЕТ, то это ваша игра, а не моя. Люди, которые действительно заботятся о своей работе, всегда будут стремиться улучшить свои навыки, понимание и самих себя, а не оправдывать то, что легко использовать, но также легко сломать. На самом деле, сделать это правильно, используя настоящие стандарты, несложно, и люди могут либо делать что-то прямо сейчас, либо создавать новые неприятности в будущем.
innerHTML в большинстве случаев лучше альтернатив. Слезь с высокого коня! Это быстрее, эффективнее и не требует повторного рендеринга страницы.
@RozzA 92KB действительно большой. Пока LTE не созреет, GPRS является Стандарт мобильной передачи данных WW, и он начинается с 1 KB/s. Посчитайте сами.
Вот минималистичное использование библиотеки ZeroClipboard JS: jsfiddle.net/N36uH
Вот еще 2 простых примера для начала jsfiddle.net/c3DUZ и jsfiddle.net/69RLv
@AdrienBe ни один из ваших примеров не работает для меня ни в Firefox, ни в Chrome
@AdrienBe Они здесь тоже не работают. На консоли ошибок нет, только предупреждения. Большинство из них с jshint.js
@GuiImamura и bhan: извините, ребята, я пока не могу помочь. Попробуйте демонстрацию на странице ZeroClipboard и посмотрите, сможете ли вы использовать этот код для начала.
Страница, на которую указывает ссылка, теперь мертва, есть только мусор, проверяющий мошенничество.
Автоматическое копирование в буфер обмена может быть опасным, и поэтому большинство браузеров (кроме Internet Explorer) очень затрудняют его. Лично я использую такой простой прием:
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>Но есть ограничение на количество символов, отображаемых в этом диалоговом окне, и, таким образом, есть ограничение на количество данных, которые должны быть скопированы.
Умно, но поддерживает только одну строку.
Изменить функцию «подсказки» на настраиваемый модальный элемент тривиально, суть трюка заключается в использовании редактируемого поля содержимого и предварительном выборе текста, и что это не нарушает пользовательский интерфейс браузера, заставляя пользователя использовать сами действия. А ++
Во-первых, отличное решение =] Но нельзя ли воспроизвести эту функциональность без js? (Не так просто, конечно.)
Если ваш текст превышает 2000 символов, он будет усечен, но для небольших образцов текста он отлично работает.
@RasTheDestroyer - усечение до 2k символов кажется проблемой Chrome, но это полезно знать, несмотря на это
@AramKocharyan Я пробовал новые строки в Chrome и IE, и оба работали для меня, он представляет его без новых строк, но когда вы вставляете информацию в редактор, новые строки сохраняются - в любом случае IE10 и Chrome29
Это настолько простой способ сделать это .. Спасибо .. Но текст не выделен .. Есть ли способ предварительно выделить текст?
Не работает в Firefox 25.0 на OS X. Я получаю приглашение, но текстовое поле пусто. В Chrome работает.
@Qix У него 579 голосов, потому что, насколько мне известно, это невозможно сделать с помощью чистого JavaScript (если только ваша единственная цель - IE). Сайты делают это «постоянно» с помощью Flash.
Для мобильных устройств в Chrome, когда я выделяю текст в приглашении, он, по-видимому, не позволяет мне копировать, а просто вырезать.
Это расширение Ответ Чейза Зайберта с тем преимуществом, что оно будет работать для элементов IMAGE и TABLE, а не только для DIV в Internet Explorer 9.
if (document.createRange) {
// Internet Explorer 9 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 Firefox
} else {
// Internet Explorer 8 and earlier. This stuff won't work
// on Internet Explorer 9.
// (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');
}
Кажется, я неправильно понял вопрос, но для справки вы можете извлечь диапазон 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 it 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;
}
}
собственно я поправил код. Он работает во всех браузерах, но фактически не копируется в буфер обмена. Просто извлекает (вырезает), клонирует (копирует) контент через переменные. Кажется, я забыл об использовании.
Я нашел следующее решение:
Обработчик нажатия клавиши создает тег «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 did 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('Failed to paste. :(');
};
}
Применение:
enyby_clip = new EnybyClipboard(); // Init
enyby_clip.copyText('some_text'); // Place this in the 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: Возможно, это решение можно использовать для создания полноценного кросс-браузерного решения без Flash. Работает в Firefox и Chrome.
Кто-нибудь пробовал это? Звучит как отличная штука, если она действительно работает в разных браузерах!
Для IE нужно запустить фокус на элементе внутри страницы. См. fiddle.jshell.net/H2FHC/3/show и fiddle.jshell.net/H2FHC/3 Работает в IE 9/10. IE 6/7 необходимо обработать выделение другим способом, потому что document.createRange не поддерживается.
Мне нравится этот:
<input onclick = "this.select();" type='text' value='copy me' />
Если пользователь не знает, как копировать текст в своей ОС, скорее всего, он тоже не знает, как вставить. Так что просто выберите его автоматически, а все остальное предоставьте пользователю.
Если скопированная ссылка должна быть вставлена на тот же сайт, то простое решение - выделить текст перед нажатием простой кнопки копирования HTML, а затем при ее нажатии текстовое содержимое сохраняется в сеансе. И куда бы его ни наклеили, есть кнопка вставки.
** Знаю, это не стойкое и универсальное решение, но это что-то :)
Вы должны показать здесь примеры кода - псевдокод - это нет, чего хотят другие разработчики. В нынешнем состоянии это не очень хороший ответ.
@Jimbo, решение ниже: для буфера обмена на основе сеанса
Помните, что сеанс ограничен 5 МБ (afaik).
Вот буфер обмена на основе 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();
}
}
?>
Это единственный ответ здесь, который не требует принуждения браузера к тому, для чего он не предназначен. Твердый +1.
Виноват. Это работает только в Internet Explorer.
Вот еще один способ скопировать текст:
<p>
<a onclick = "window.clipboardData.setData('text', document.getElementById('Test').innerText);">Copy</a>
</p>
Это не работает в текущих версиях Chrome (V31) или FireFox (v25). Ошибка в том, что window.clipboardData не определено. С другой стороны, это работает в IE9. Итак, пока вы не заботитесь о хороших браузерах и хотите заблокировать свой сайт для использования плохих, это ваш способ сделать это!
Я не понимаю, почему так много глупых ответов. w3schools.com/howto/tryit.asp?filename=tryhow_js_copy_clipbo ard
Если вы читаете текст из буфера обмена в расширении 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;
}
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);
});
});
https://github.com/zeroclipboard/ZeroClipboard
кроссбраузерность с Flash? не работает в iOS и Android 4.4
См. Обновленный ответ. Это позволяет меньше шагов для пользователей flash и откат для всех остальных.
в нем миллиард строк кода. это абсолютно насмешки. лучше вообще этого не делать, чем включать такого монстра в проект
Существует простая версия gist.github.com/JamesMGreene/8698897, которая составляет 20K, которая не имеет всех наворотов в версии 74k. Ни то, ни другое не очень большое. Я предполагаю, что большинство пользователей в порядке с дополнительными миллисекундами, которые потребуются для загрузки файла размером 74 КБ или 20 КБ, поэтому копирование / вставка выполняется одним щелчком мыши вместо двух.
@Justin Я просто не могу заставить его работать локально, даже если я копирую и вставляю примеры (я вношу минимальные изменения, например, значение src в тегах скрипта). Я считаю, что их документация хороша, но неэффективна.
В Chrome вы можете использовать copy('the text or variable etc'). Хотя это не кроссбраузерность (и не работает в сниппете?), вы можете добавить его к другим кроссбраузерным ответам.
Это работает только при вводе в командной строке Chrome. Когда я добавляю его в свой код, функция копирования не определяется.
@JoeCoder благодарим вас за явное указание на это, поскольку я имел в виду, что это должно быть очевидно из ссылки, но, оглядываясь назад, это не очень очевидно.
Я недавно написал сообщение в техническом блоге по этой самой проблеме (я работаю в 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, что является единственным кроссбраузерным способом сделать это (насколько я понимаю).
Помимо этого, есть несколько вариантов для каждого браузера.
Это самый простой вариант в Internet Explorer, где вы можете получить доступ к объекту clipboardData в любое время из JavaScript с помощью:
window.clipboardData
(Однако, когда вы пытаетесь сделать это вне системного события вырезания, копирования или вставки, Internet Explorer предложит пользователю предоставить разрешение буфера обмена веб-приложения.)
В Chrome вы можете создать расширение Chrome, которое даст вам разрешения буфера обмена (это то, что мы делаем для Lucidchart). Тогда для пользователей с установленным расширением вам просто нужно самостоятельно запустить системное событие:
document.execCommand('copy');
Похоже, что в Firefox есть некоторые варианты, который позволяет пользователям предоставлять разрешения определенным сайтам на доступ к буферу обмена, но я лично не пробовал ничего из этого.
В сообщении блога не упоминается (я надеюсь обновить его в ближайшем будущем), это возможность запускать вырезание и копирование с помощью execCommand. Это поддерживается в IE10 +, Chrome 43+ и Opera29 +. Об этом читайте здесь. updates.html5rocks.com/2015/04/cut-and-copy-commands
Проблема в том, что он перехватывает другие обычные события копирования.
NB! Это обнюхивание браузера ПЛОХО. Обнюхивайте особенности. Вы затрудняете обновление IE.
Вы не можете этого сделать из соображений безопасности. Вы должны выбрать Flash для копирования в буфер обмена.
Я предлагаю этот: http://zeroclipboard.org/
Это немного комбинация других ответов.
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"/>' )
Как скопировать данные напрямую из переменной. Т.е. var str = "word"; ?
Сообщение переменной не используется
Лучше использовать '<textarea class = "textToCopyInput" /> </textarea> в случае, если textToCopy содержит \n
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.info('success'); },
function(err){console.info('failure', err);
});
});
</script>
clipboard.js также находится на GitHub.
Note: This has been deprecated now. Migrate to here.
Эта библиотека используется angular.io для его Tour of Hero и отката в изящном режиме для браузера, не поддерживающего execCommand, путем отображения предварительно выбранного текста, который пользователь должен просто скопировать.
Похоже, clipboard.js был заменен или разветвлен, но, похоже, он живет и активно поддерживается в npmjs.com/package/clipboard
В дополнение к Обновленный ответ Дина Тейлора (июль 2015 г.) я написал метод jQuery, похожий на его пример.
/**
* 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();
}
};
Обновление 2015: в настоящее время есть способ использовать document.execCommand для работы с буфером обмена.
clipboard.js обеспечивает кроссбраузерный способ работы с буфером обмена (поддержка браузера).
Я собирался использовать clipboard.js, но у него нет мобильного решения (пока) ... поэтому я написал супер-маленькую библиотеку:
Это либо скопирует текст (рабочий стол, Android и Safari 10+), либо, по крайней мере, выделит текст (более старые версии iOS). В уменьшенном виде это чуть более 1 КБ. В настольном Safari (до версии 10) он сообщает пользователю "Нажмите Command + C, чтобы скопировать". Вам также не нужно писать какой-либо JavaScript, чтобы использовать его.
Я использовал clipboard.js.
Мы можем получить его на npm:
npm install clipboard --save
А также на Беседка
bower install clipboard --save
Использование и примеры находятся на https://zenorocha.github.io/clipboard.js/.
Я боялся, что это несовместимо с динамическим контентом, но это так ;-) Я думаю, что это лучшее решение СЕЙЧАС, чем старое решение 2008 года.
Поскольку Chrome 42+ и Firefox 41+ теперь поддерживают команду document.execCommand ('копия'), я создал несколько функций для кросс-браузерного копирования в буфер обмена, используя комбинацию Старый ответ Тима Дауна и Ответ разработчика Google:
function selectElementContents(el) {
// Copy textarea, pre, div, etc.
if (document.body.createTextRange) {
// Internet Explorer
var textRange = document.body.createTextRange();
textRange.moveToElementText(el);
textRange.select();
textRange.execCommand("Copy");
}
else if (window.getSelection && document.createRange) {
// Non-Internet Explorer
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.info('Copy command was ' + msg);
}
catch (err) {
console.info('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 Internet Explorer 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>Спасибо за подведение итогов! В вашем коде есть небольшие ошибки: вы дважды определили переменную "диапазон" (var range = document.createRange ()).
Вы правы @ChristianEngel. Я удалил второй. Не знаю, как он туда попал.
Следующий подход работает в Chrome, Firefox, Internet Explorer и Edge, а также в последних версиях Safari (поддержка копирования была добавлена в версии 10, выпущенной в октябре 2016 года).
Примечание: вы не увидите текстовое поле, поскольку оно добавляется и удаляется при одном синхронном вызове кода Javascript.
Некоторые вещи, на которые следует обратить внимание, если вы реализуете это самостоятельно:
Приведенная ниже функция должна обрабатывать все следующие проблемы как можно более четко. Пожалуйста, оставьте комментарий, если вы обнаружите какие-либо проблемы или у вас есть предложения по его улучшению.
// 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 Internet Explorer 10+.
// Internet Explorer: 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) {
// Internet Explorer-specific code path to prevent textarea being shown while dialog is visible.
return window.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 Microsoft 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/
Хороший ответ: кроссбраузерная поддержка, обработка ошибок + очистка. Что касается сегодняшней новой поддержки queryCommandSupported, копирование в буфер обмена теперь возможно в Javascript, и это должен быть принятый ответ вместо неудобного обходного пути 'window.prompt («Копировать в буфер обмена: Ctrl + C, Enter», текст) ». window.clipboardData поддерживается в IE9, поэтому вам следует добавить IE9 в список поддержки браузера, и я думаю, может быть, IE8 и предыдущие также, но необходимо проверить.
Ага. IE 8/9 Должно быть в порядке. Наше приложение их не поддерживает. Так что я не тестировал. IE прекращает поддержку в январе, так что я не особо волнуюсь. Надеюсь, поддержка Safari скоро появится. Я уверен, что это на их радарах.
@SantiagoCorredoira: В 2016 году это заслуживает общепринятого ответа. Пожалуйста, рассмотрите возможность переназначения BGT (большая зеленая галочка).
@drooh Поддерживается в Safari 10+. Safari 10 все еще находится в стадии бета-тестирования. Он будет выпущен вместе с MacOS 10.12 (вероятно, в октябре).
textarea.select () у меня не работает в Chrome. Функция существует, но содержимое текстовой области фактически не попадает в буфер обмена.
Вы пробовали код на JS Fiddle? jsfiddle.net/fx6a6n6x У меня это работает в chrome и canary на MacOS.
Если фокус не находится в html-документе, например, вы просто щелкнули панель задач Windows, а затем нажали кнопку «Копировать» в своем html-документе, функция вернет true, но не сможет скопировать. Так было в Firefox 55 сегодня. Но спасибо, что поделились этим, я использую его, очень признателен.
@Noitidart Я протестирован, и он отлично работает для firefox 54, chrome 60 и браузера Edge, даже когда фокус не находится в html-документе, ошибка, которую вы имеете, вероятно, специфична для версии FF 55
Спасибо, @TosinJohn - пожалуйста, откройте инструменты разработчика, затем сфокусируйтесь на них, затем с помощью первого щелчка - щелкните <button>, который запускает копирование, он должен вернуть истину, но копия не удастся.
@Noitidart Здесь он по-прежнему отлично работает, сосредоточение внимания на инструментах разработчика не остановило его. И, кстати, что будет делать обычный пользователь веб-приложения с инструментами разработчика?
Спасибо @TosinJohn - это очень интересно. Я не знаю, почему моя первая копия выходит из строя. Большое спасибо за этот тест. Да, правда, их может не быть в инструментах разработчика, но у них может быть два окна рядом друг с другом, и они могут щелкнуть из одного окна в мое веб-приложение (сначала щелкните копию).
команда: clipboardData, setData ("Text", text) не копирует форматированный текст, поэтому, например, если вы скопировали текст, содержащий несколько строк (с символами новой строки в качестве разделителей), символ новой строки не будет часть скопированной строки, и вместо этого вы получите одну длинную строку
Я, вероятно, задаю неправильные вопросы в неправильном месте, но все равно хочу попробовать ... можно ли сделать это в виде двух лайнеров, используя какой-то надежный, всегда обновляемый импорт из gitlab или что-то в этом роде?
нуждается в исправлении, есть отличное средство «если» для проверки доступности window.clipboardData.setData, но затем, если оно проходит, код обходит окно и напрямую попадает в «clipboardData»! Я добавил код asis в CRA, и он разлетелся, просто нужно окно. приставка
После поиска решения, поддерживающего Safari и другие браузеры (Internet Explorer 9 и более поздние версии),
Я использую то же, что и 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>
JavaScript
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"]);
});
});
Ответов уже много, но хотелось бы добавить еще один (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.');
}
Мне пришлось скопировать текст без полей ввода (текст в любом теге div / span) со страницы и придумал следующий код. Единственная уловка - иметь скрытое поле, но типа ТЕКСТ. Он не будет работать со скрытым типом.
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" />
...
Я нашел следующее решение:
У меня есть текст в скрытом вводе. Поскольку 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;
}
Я скомпилировал несколько функций в простое решение, охватывающее все случаи, с возможностью быстрого отката в случае необходимости.
window.copyToClipboard = function(text) {
// Internet Explorer specific
if (window.clipboardData && window.clipboardData.setData) {
return clipboardData.setData("Text", text);
}
// All other modern browsers
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.info('Copied to clipboard: "'+text+'"');
}
catch(e) {
console.info("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/
Я собрал решение, представленное здесь @ 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 выше.
Я собрал то, что считаю лучшим.
Вот:
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 programmatic 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')
Это лучшее. Так много побед.
var toClipboard = function(text) {
var doc = document;
// Create temporary 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;
}
textarea.style.position = 'fixed'; будет лучше
@liubiantao, почему это так?
Вот мой взгляд на это ...
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;
}
@korayem: Обратите внимание, что при использовании поля html input не будут учитываться разрывы строк \n и любой текст будет сведен в одну строку.
Как упоминал @nikksan в комментариях, использование textarea решит проблему следующим образом:
function copy(text) {
var input = document.createElement('textarea');
input.innerHTML = text;
document.body.appendChild(input);
input.select();
var result = document.execCommand('copy');
document.body.removeChild(input);
return result;
}
@nikksan как скопировать строку с \n?
@ sof-03 используйте textarea вместо input и добавьте \r\n для разрыва строки
Не работает в Microsoft Edge 42.17134.1.0 на Win10x64
Я скопировал ваш ответ. Он работает в хроме, и это все, что мне нужно.
Это простейшее решение, которое работает с Firefox v68.0.2 (64-бит).
По какой-то причине мой обычный «создать скрытый ввод или текстовое поле, затем выбрать его и execCommand» не работал, и это было, безусловно, лучшее решение, перечисленное здесь, хотя другие всеобъемлющие и, как и полные страницы википедии, это работало хорошо для меня так +1
Это была единственная вещь, с которой я когда-либо работал, после того, как искал различные способы по всему Интернету. Это грязная тема. По всему миру опубликовано множество решений, и большинство из них работают с нет. Это сработало для меня:
ПРИМЕЧАНИЕ. Этот код будет работать только при выполнении как прямой синхронный код для чего-то вроде метода 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();
}
Я понимаю, что этот код будет отображать компонент шириной в 1 пиксель на экране в течение миллисекунды, но решил не беспокоиться об этом, и это то, что другие могут решить, если возникнет реальная проблема.
Чтобы скопировать выделенный текст («Текст для копирования») в буфер обмена, создайте букмарклет (закладку браузера, которая выполняет JavaScript) и выполните его (щелкните по нему). Это создаст временную текстовую область.
Код с 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');
Это единственное, что у меня сработало:
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');
Используя функцию JavaScript с помощью try/catch, вы можете даже лучше обрабатывать ошибки, делая это следующим образом:
copyToClipboard() {
let el = document.getElementById('Test').innerText
el.focus(); // el.select();
try {
var successful = document.execCommand('copy');
if (successful) {
console.info('Copied Successfully! Do whatever you want next');
}
else {
throw ('Unable to copy');
}
}
catch (err) {
console.warn('Oops, Something went wrong ', err);
}
}
Что здесь ES7?
блок try / catch
Если только я не понимаю, что вы имеете в виду, try...catch существует со времен "ES3" (то есть за последние 20 лет или около того).
Извините, сэр, это было моим незнанием. Я поправил свой пост.
Скопируйте текст из ввода 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() не поддерживается в Internet Explorer 9 и более ранних версиях.
Источник: W3Schools - Копировать текст в буфер обмена
Вот элегантное решение для 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;
}
Вот мое решение:
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();
}
Я очень успешно использую это (без 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).
Вот как это сделать в 2018 году:
async copySomething(text?) {
try {
const toCopy = text || location.href;
await navigator.clipboard.writeText(toCopy);
console.info('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-адрес страницы.
Можно сделать еще больше гимнастики для буфера обмена. См. Дополнительную информацию здесь:
Разблокировка доступа к буферу обмена
вы связались с localhost
Имейте в виду, что это не работает в Safari (версия 11.1.2).
@ arjun27 Что ж, надеюсь, когда-нибудь Apple наверстает упущенное. Хотя этот caniuse.com/#feat=clipboard показывает, что упомянутая выше версия частично поддерживается.
Полезный контент; бесполезное отношение.
Я получаю для обеих функций readText, writeText обещание в отклоненном состоянии
Согласно предоставленной ссылке, "navigator.clipboard поддерживается только для страниц, обслуживаемых через HTTPS".
Это может может быть выполнено с помощью комбинации getElementbyId, Select (), blur () и команды копирования.
Примечание
Метод select () выбирает весь текст в элементе <textarea> или элементе <input> с текстовым полем. Это может не работать с кнопкой.
Применение
let copyText = document.getElementById('input-field');
copyText.select()
document.execCommand("copy");
copyReferal.blur()
document.getElementbyId('help-text').textContent = 'Copied'
Метод blur () удалит некрасиво выделенную часть вместо того, что вы можете показать в красивом сообщении, что ваш контент был успешно скопирован.
Использование document.execCommand сделает всю работу за вас ...
Используя это, вы также можете использовать резать, копировать и вставить ...
Это одна простая функция копирования из буфера обмена, которая копирует все из входного текста ...
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>Для получения дополнительной информации см. Взаимодействовать с буфером обмена (надстройка).
Я пробовал много решений. Если он работает в современных браузерах, то не в Internet Explorer. Если он работает в Internet Explorer, то не на iOS. Я, наконец, обработал их все и пришел к исправлению ниже, которое работает во всех браузерах, iOS, webview и Android.
Примечание. Я также рассмотрел сценарий, в котором пользователь запрещает доступ к буферу обмена. Кроме того, сообщение «ссылка скопирована» будет отображаться, даже если пользователь копирует вручную.
<div class = "form-group col-md-12">
<div class = "input-group col-md-9">
<input name = "copyurl"
type = "text"
class = "form-control br-0 no-focus"
id = "invite-url"
placeholder = "http://www.invitelink.com/example"
readonly>
<span class = "input-group-addon" id = "copy-link" title = "Click here to copy the invite link">
<i class = "fa fa-clone txt-18 text-success" aria-hidden = "true"></i>
</span>
</div>
<span class = "text-success copy-success hidden">Link copied.</span>
</div>
Сценарий:
var addEvent = window.attachEvent || window.addEventListener;
var event = 'copy';
var $inviteUrl = $('#invite-url');
$('#copy-link').on('click', function(e) {
if ($inviteUrl.val()) {
if (navigator.userAgent.match(/ipad|ipod|iphone/i)) {
var el = $inviteUrl.get(0);
var editable = el.contentEditable;
var readOnly = el.readOnly;
el.contentEditable = true;
el.readOnly = false;
var range = document.createRange();
range.selectNodeContents(el);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
el.setSelectionRange(0, 999999);
el.contentEditable = editable;
el.readOnly = readOnly;
document.execCommand('copy');
$inviteUrl.blur();
}
else {
$inviteUrl.select();
document.execCommand("copy");
}
}
});
addEvent(event, function(event) {
if ($inviteUrl.val() && event.target.id == 'invite-url') {
var $copyLink = $('#copy-link i');
$copyLink.removeClass('fa-clone');
$copyLink.addClass('fa-check');
$('.copy-success').removeClass('hidden');
setTimeout(function() {
$copyLink.removeClass('fa-check');
$copyLink.addClass('fa-clone');
$('.copy-success').addClass('hidden');
}, 2000);
}
});
Вот простой пример;)
<!DOCTYPE html>
<html>
<body>
<input type = "text"
value = "Hello, World!"
id = "myInput">
<button onclick = "myFunction()">Copy text</button>
<p>The document.execCommand() method is not supported
in Internet Explorer 8 and earlier.</p>
<script>
function myFunction() {
var copyText = document.getElementById("myInput");
copyText.select();
document.execCommand("copy");
alert("Copied the text: " + copyText.value);
}
</script>
</body>
</html>
Это автономный класс, который гарантирует невозможность перепрограммирования временного textarea, помещая его за пределы экрана.
Это работает в Safari (рабочий стол), Firefox и Chrome.
// ================================================================================
// ClipboardClass
// ================================================================================
var ClipboardClass = (function() {
function copyText(text) {
// Create a temporary element off-screen to hold text.
var tempElem = $('<textarea style = "position: absolute; top: -8888px; left: -8888px">');
$("body").append(tempElem);
tempElem.val(text).select();
document.execCommand("copy");
tempElem.remove();
}
// ============================================================================
// Class API
// ============================================================================
return {
copyText: copyText
};
})();
function copytoclipboard(element) {
var $temp = $("<input>");
$("body").append($temp);
$temp.val('0' + element).select();
document.execCommand("copy");
$temp.remove();
}
$("td").click(function (e) {
var clickedCell = $(e.target).closest("td");
navigator.clipboard.writeText(clickedCell.text());
alert(clickedCell.text());
});<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td>First<td>
</tr>
<tr>
<td>Second<td>
</tr>
<tr>
<td>Third<td>
</tr>
<tr>
<td>Fourth<td>
</tr>
</table>Я прочитал все ответы, по состоянию на 1 июня 2020 года я изо всех сил пытался решить эту проблему, когда наконец нашел документацию:
$("td").click(function (e) {
var clickedCell = $(e.target).closest("td");
navigator.clipboard.writeText(clickedCell.text());
});
Он запишет текст выбранной ячейки в буфер обмена браузера.
Вы можете изменить селекторы «td» на все, что захотите, вы можете добавить console.info для функций отладки и / или предупреждений.
Вот документация: https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/writeText
Нет совместимости с IE
document.querySelector('#some_your_textfield_id').select();
document.execCommand('copy');
Первая строка - выделить текст, который вы хотите скопировать.
Вторая строка предназначена для копирования выделенного текста.
Это решение было найдено здесь. document.execCommand("copy"); не поддерживается в Internet Explorer 8 и более ранних версиях.
const copyBtn = document.getElementById("copyBtn");
const input = document.getElementById("input");
function copyText() {
const value = input.value;
input.select(); // selects the input variable as the text to be copied
input.setSelectionRange(0, 99999); // this is used to set the selection range for mobile devices
document.execCommand("copy"); // copies the selected text
alert("Copied the text " + value); // displays the copied text in a prompt
}
copyBtn.onmousedown = function () {
copyText();
}<input type = "text" id = "input" placeholder = "Type text to copy... "/>
<button id = "copyBtn">
Copy
</button>Команда execCommand считается устаревшей: developer.mozilla.org/en-US/docs/Web/API/Document/execComman d
Простое, готовое к использованию и не устаревшее решение:
function copyToClipboard(elementIdToCopy, elementIdToNotifyOutcome) {
const contentToCopy = document.getElementById(elementIdToCopy).innerHTML;
const elementToNotifyOutcome = document.getElementById(elementIdToNotifyOutcome);
navigator.clipboard.writeText(contentToCopy).then(function() {
elementToNotifyOutcome.classList.add('success');
elementToNotifyOutcome.innerHTML = 'Copied!';
}, function() {
elementToNotifyOutcome.classList.add('failure');
elementToNotifyOutcome.innerHTML = 'Sorry, did not work.';
});
}
Приведенную ниже функцию можно использовать для копирования в буфер обмена:
copyToclipboard = (event, text) => {
var container = event.currentTarget;
let tempInnerHtml = container.innerHTML;
container.innerHTML = text;
window.getSelection().removeAllRanges();
let range = document.createRange();
range.selectNode(container);
window.getSelection().addRange(range);
document.execCommand('copy');
window.getSelection().removeAllRanges();
container.innerHTML = tempInnerHtml;
}
execCommand теперь считается устаревшим: developer.mozilla.org/en-US/docs/Web/API/Document/execComman d
Это может быть решением вашей проблемы
function CopyToNotepad(id){
var r = document.createRange();
r.selectNode(document.getElementById(id));
window.getSelection().removeAllRanges();
window.getSelection().addRange(r);
document.execCommand('copy');
window.getSelection().removeAllRanges();
}
Просто любопытно, что вы хотите скопировать в буфер обмена, чего пользователь не может сделать сам?