Копировать в буфер обмена в расширении Chrome
Я делаю расширение для Google Chrome и попал в ловушку.
Мне нужно скопировать содержимое текстовой области только для чтения в буфер обмена при нажатии во всплывающем окне. Кто-нибудь знает лучший способ сделать это с чистым Javascript и без Flash? У меня также есть jQuery, загруженный в расширение, если это помогает. Мой текущий (нерабочий) код...
function copyHTMLCB() {
$('#lb_html').select();
$('#lb_html').focus();
textRange = document.lb_html_frm.lb_html.createTextRange();
textRange.execCommand("RemoveFormat");
textRange.execCommand("Copy");
alert("HTML has been copied to your clipboard."); }
12 ответов
Вы можете скопировать в буфер обмена с помощью Experimental Clipboard API, но он доступен только в ветке dev браузера и не включен по умолчанию ( подробнее).
Вся заслуга принадлежит joelpt, но в случае, если кому-то еще это нужно для работы в чистом javascript без jQuery (я это сделал), вот адаптация его решения:
function copyTextToClipboard(text) {
//Create a textbox field where we can insert text to.
var copyFrom = document.createElement("textarea");
//Set the text content to be the text you wished to copy.
copyFrom.textContent = text;
//Append the textbox field into the body as a child.
//"execCommand()" only works when there exists selected text, and the text is inside
//document.body (meaning the text is part of a valid rendered HTML element).
document.body.appendChild(copyFrom);
//Select all the text!
copyFrom.select();
//Execute command
document.execCommand('copy');
//(Optional) De-select the text using blur().
copyFrom.blur();
//Remove the textbox field from the document.body, so no other JavaScript nor
//other elements can get access to this.
document.body.removeChild(copyFrom);
}
Я обнаружил, что следующее работает лучше всего, поскольку позволяет указать тип MIME копируемых данных:
copy: function(str, mimeType) {
document.oncopy = function(event) {
event.clipboardData.setData(mimeType, str);
event.preventDefault();
};
document.execCommand("copy", false, null);
}
Я использую эту простую функцию для копирования любого данного открытого текста в буфер обмена (только Chrome, использует jQuery):
// Copy provided text to the clipboard.
function copyTextToClipboard(text) {
var copyFrom = $('<textarea/>');
copyFrom.text(text);
$('body').append(copyFrom);
copyFrom.select();
document.execCommand('copy');
copyFrom.remove();
}
// Usage example
copyTextToClipboard('This text will be copied to the clipboard.');
Из-за быстрой последовательности append-select-copy-remove, по-видимому, нет необходимости скрывать текстовую область или присваивать ей какие-либо конкретные CSS/ атрибуты. По крайней мере, на моем компьютере Chrome даже не выводит его на экран до удаления, даже с очень большими кусками текста.
Обратите внимание, что это будет работать только в расширении / приложении Chrome. Если вы используете v2 manifest.json, вы должны объявить там разрешение 'clipboardWrite'; это обязательно для приложений и рекомендуется для расширений.
Clipboard API теперь поддерживает Chrome, и предназначен для заменыdocument.execCommand
.
Из MDN:
navigator.clipboard.writeText(text).then(() => {
//clipboard successfully set
}, () => {
//clipboard write failed, use fallback
});
Вы не можете скопировать бит текста только для чтения, используя execCommand("Copy")
, это должна быть редактируемая текстовая область. Решение состоит в том, чтобы создать элемент ввода текста и скопировать текст оттуда. К сожалению, вы не можете скрыть этот элемент, используя display: none
или же visibility: hidden
так как это также остановит работу команды select / copy. Однако вы можете "спрятать" его, используя отрицательные поля. Вот что я сделал во всплывающем окне Chrome Extension, которое получает короткий URL-адрес. Это фрагмент кода, который переписывает всплывающее окно с помощью shorturl (быстрый и грязный подход;-)):
document.body.innerHTML = '<p><a href="'+shortlink+'" target="_blank" >'+shortlink+'</a><form style="margin-top: -35px; margin-left: -500px;"><input type="text" id="shortlink" value="'+shortlink+'"></form></p>'
document.getElementById("shortlink").select()
document.execCommand("Copy")
Только это сработало для меня.
document.execCommand вообще не работает для хрома, как мне кажется.
Я оставил execCommand в коде, но, наверное, по одной простой причине: Чтобы это дерьмо просто было :)
Я потратил на это много времени вместо того, чтобы просмотреть свои старые записи.
function copy(str, mimeType) {
document.oncopy = function(event) {
event.clipboardData.setData(mimeType, str);
event.preventDefault();
};
try{
var successful = document.execCommand('copy', false, null);
var msg = successful ? 'successful' : 'unsuccessful';
console.log('Copying text command was ' + msg);
if (!successful){
navigator.clipboard.writeText(str).then(
function() {
console.log('successful')
},
function() {
console.log('unsuccessful')
}
);
}
}catch(ex){console.log('Wow! Clipboard Exeption.\n'+ex)}
}
Я где-то читал, что есть ограничения безопасности с Javascript, который мешает вам взаимодействовать с ОС. В прошлом у меня был хороший успех с ZeroClipboard ( http://code.google.com/p/zeroclipboard/), но он использует Flash. Сайт Bitly использует его довольно эффективно: http://bit.ly/
let content = document.getElementById("con");
content.select();
document.execCommand("copy");
Приведенный выше код отлично работает в любом случае. Просто убедитесь, что поле, из которого вы берете контент, должно быть редактируемым полем, таким как поле ввода.
Я обнаружил, что ответ gjuggler работает, но он блокирует любую копию, которую пользователь может сделать в браузере, поэтому, если вы просто хотите установить значение копирования один раз только при нажатии кнопки, используйте эту функцию следующим образом.
function setCopyValueOnce(val){
function setCopyOnce(event) {
console.log("hi");
event.clipboardData.setData('Text', val);
event.preventDefault();
}
document.addEventListener('copy', setCopyOnce);
document.execCommand("copy", false, null);
document.removeEventListener('copy', setCopyOnce);
}
setCopyValueOnce($("textarea").val());
Я использовал RemoveEventListener, чтобы остановить созданный прослушиватель событий копирования.
Я пытаюсь создать расширение для Chrome, которое будет копировать данные прямо в буфер обмена при нажатии кнопки, но я не смог найти никакой соответствующей информации по этому поводу; перепробовал много всего из разных тем здесь.
Я нашел расширение , которое автоматически копирует текст после его выделения, но у меня оно не работает
Этот плагин у меня не работает, но если я вставлю его код в свое собственное расширение, он будет работать нормально
window.addEventListener(
'mouseup',
() => {
const content = document.getSelection()?.toString();
if (!content) { return; }
navigator.clipboard.writeText(content);
},
false
);
У меня была похожая проблема, когда мне приходилось копировать текст из элемента, используя только JavaScript. Я добавлю решение этой проблемы здесь для всех, кто заинтересован. Это решение работает для многих элементов HTML, включая textarea.
HTML:
<textarea id="text-to-copy">This is the text I want to copy</textarea>
<span id="span-text-to-copy">This is the text I want to copy</span>
Javascript:
let textElement = document.getElementById("text-to-copy");
//remove selection of text before copying. We can also call this after copying
window.getSelection().removeAllRanges();
//create a Range object
let range = document.createRange();
//set the Range to contain a text node.
range.selectNode(textElement);
//Select the text node
window.getSelection().addRange(range);
try {
//copy text
document.execCommand('copy');
} catch(err) {
console.log("Not able to copy ");
}
Обратите внимание, что если вы хотите скопировать элемент span, например, вы можете получить его текстовый узел и использовать его в качестве параметра для range.selectNode(), чтобы выделить этот текст:
let elementSpan = document.getElementById("span-text-to-copy");
let textNode = elementSpan.childNodes[0];