Использование execCommand (Javascript) для копирования скрытого текста в буфер обмена
Я пытаюсь скопировать в буфер обмена без использования Flash, я планирую вернуться на Flash с помощью ZeroClipboard, если браузер несовместим с подходом javascript.
У меня есть слушатель onClick для кнопки, которая выглядит так:
$(buttonWhereActionWillBeTriggered).click(function(){
var copyDiv = document.getElementById(inputContainingTextToBeCopied);
copyDiv.focus();
document.execCommand('SelectAll');
document.execCommand("Copy", false, null);
}
и поле ввода следующим образом:
<input type="text" name="Element To Be Copied" id="inputContainingTextToBeCopied" value="foo"/>
В настоящее время это работает так, как ожидалось, но для дизайна требуется, чтобы поле, содержащее текст, который нужно скопировать, невидимо. Я попробовал установить type="hidden"
и style="display: none"
, ни один из которых не удалось. Оба приводят к тому, что кнопка выбирает всю страницу и копирует весь контент в пользовательский буфер обмена.
Я уверен, что причина не в браузере, а просто в том, что я тестирую Chrome (версия 43.0.2357.134 (64-разрядная версия)) в Mac OS X 10.10.4.
Есть ли способ, которым я могу поддерживать функциональность, когда < вход > виден во время его скрытия? или если не альтернативный маршрут, который я могу взять?
Я знаю похожие вопросы, ни одна из которых не затрагивает мою проблему, либо из-за того, что она слишком стар, а не на самом деле не использует Javascript или не подходит для конкретного сценария. Здесь хороший ответ для тех, у кого есть похожие, менее конкретные проблемы.
Ответы
Ответ 1
- Update -
Document.execCommand()
[1] До Firefox 41 необходимо, чтобы функция буфера обмена была включена в файле настроек user.js. Подробнее см. В кратком руководстве по настройкам Mozilla. Если команда не поддерживалась или не была включена, execCommand создавал исключение вместо того, чтобы возвращать false. В Firefox 41 и более поздних версиях функция буфера обмена включена по умолчанию в любом обработчике событий, который может всплывать окно (полунадежные скрипты).
Так как Firefox версии 41 теперь работает Document.execCommand(). Поэтому больше не нужно использовать резервную копию.
Поскольку браузеры, похоже, ведут себя по-разному, когда дело доходит до доступа к буферу,
мне потребовалось некоторое время, чтобы обнять его вокруг.
Это очень похоже на ваше решение, но разница заключается в создании временного элемента и его заполнении с помощью ввода value
. Таким образом, мы можем сохранить свойство ввода display
равным none
.
Существует также обходной путь для IE, который использует window.clipboardData
.
Firefox не позволит мне получить доступ к буферу вообще. Поэтому мне пришлось добавить prompt
, чтобы пользователи вручную копировали входное значение. Конечно, prompt
является уродливым, но вы можете просто использовать модальное окно, которое будет делать то же самое.
Так как это кажется узловатым, я нахожусь на Win7 (64 бит) и тестировался в
Chrome - версия 43.0.2357.134 м
IE - версия 11.0.9600.17914
и Firefox не имеет значения, потому что он не позволит мне получить к нему доступ в любом случае.
var copyBtn = $("#copy-btn"),
input = $("#copy-me");
function copyToClipboardFF(text) {
window.prompt ("Copy to clipboard: Ctrl C, Enter", text);
}
function copyToClipboard() {
var success = true,
range = document.createRange(),
selection;
// For IE.
if (window.clipboardData) {
window.clipboardData.setData("Text", input.val());
} else {
// Create a temporary element off screen.
var tmpElem = $('<div>');
tmpElem.css({
position: "absolute",
left: "-1000px",
top: "-1000px",
});
// Add the input value to the temp element.
tmpElem.text(input.val());
$("body").append(tmpElem);
// Select temp element.
range.selectNodeContents(tmpElem.get(0));
selection = window.getSelection ();
selection.removeAllRanges ();
selection.addRange (range);
// Lets copy.
try {
success = document.execCommand ("copy", false, null);
}
catch (e) {
copyToClipboardFF(input.val());
}
if (success) {
alert ("The text is on the clipboard, try to paste it!");
// remove temp element.
tmpElem.remove();
}
}
}
copyBtn.on('click', copyToClipboard);
#copy-me {
display:none
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" name="Element To Be Copied" id="copy-me" value="foo loves bar"/>
<button id="copy-btn">Copy</button><br/><br/>
<textarea placeholder="paste here"></textarea>
Ответ 2
Здесь мое решение, которое не использует jQuery:
function setClipboard(value) {
var tempInput = document.createElement("input");
tempInput.style = "position: absolute; left: -1000px; top: -1000px";
tempInput.value = value;
document.body.appendChild(tempInput);
tempInput.select();
document.execCommand("copy");
document.body.removeChild(tempInput);
}
<!DOCTYPE html>
<html>
<head>
<title>Set Clipboard</title>
</head>
<body>
<button onclick="setClipboard('foo loves bar')">Set Clipboard</button>
</body>
</html>
Ответ 3
Благодаря помощи @DavidDomain, я нашел несколько хакерский, но функциональный подход.
Во-первых, я переместил входной путь с экрана и изменил некоторые свойства, в результате получилось следующее:
<input type="text" name="Element To Be Copied" id="inputContainingTextToBeCopied" value="foo" style="display:none; position: relative; left: -10000px;"/>
display: ни один не был добавлен после следующих изменений в js
После этого комментарий @Pokkanome позволяет мне модифицировать функцию onClick следующим образом:
$(buttonWhereActionWillBeTriggered).click(function(){
var copyDiv = document.getElementById(inputContainingTextToBeCopied);
copyDiv.style.display = 'block';
copyDiv.focus();
document.execCommand('SelectAll');
document.execCommand("Copy", false, null);
copyDiv.style.display = 'none';
}
Я не уверен, возможно ли копировать скрытый div с помощью этого метода, что имеет смысл с точки зрения безопасности браузера, поскольку предоставление неоспоримого доступа к буферу будет несколько рискованным. Однако принятый подход имел тот же намеченный результат.
Ответ 4
2019 - все еще искал ответ без закадрового штучки.
Сначала я изменил поле ввода текста на type = "text", скопировал текст, а затем изменил его обратно на type = "hidden". Это хорошо работает.
<input id="dummy" name="dummy" type="hidden">
<script>
var copyText = document.getElementById("dummy");
copyText.type = 'text';
copyText.select();
document.execCommand("copy");
copyText.type = 'hidden';
</script>
Ответ 5
Этот вопрос очень старый, поэтому у меня НОВЫЙ, менее устаревший ответ.
С помощью этого скрипта можно скопировать ваши данные. это намного меньше, чем прошлые
Все, что он делает, это скрывает ваш Input WAYYY от края экрана, следовательно, делает его скрытым. В то же время сохраняя возможность копировать его (в отличие от использования дисплея: нет;)
function copyFunc() {
var copyText = document.getElementById("copyInp");
copyText.select();
document.execCommand("copy"); //this function copies the text of the input with ID "copyInp"
}
<input type="text" value="StuffYaWantCopied" id="copyInp" style="position:absolute;left:-1000px;top:-1000px;">
<a onclick="copyFunc()" style="cursor:cell;">
Click here to Copy!
</a>
Ответ 6
Что работает для меня было:
<div>
<a class="copyBtn">Copy</a>
<input class="d-none" value="teste">
</div>
и:
$('.copyBtn').on('click', function(e) {
e.preventDefault();
var input = $(this).parent().find(".dirVal");
$(input).removeClass("d-none");
input.select();
document.execCommand('copy');
$(input).addClass("d-none");
callNotify("Parabéns!", "Caminho copiado para área de transferência!", "success");
});
Ответ 7
Альтернативный обходной путь, который работает во всех браузерах, состоит в том, что вместо скрытия элемента вы можете установить его непрозрачность равной 0 с абсолютной позицией.
#copy-me {
position: absolute;
opacity: 0;
}
Ответ 8
Как насчет использования этого: https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/writeText
navigator.clipboard.writeText("<empty clipboard>").then(function() {
/* clipboard successfully set */
}, function() {
/* clipboard write failed */
});
Ответ 9
Здесь простой, но хакерский ответ на этот вопрос, который, кажется, работает для меня. Вместо использования display: none;
использовать этот:
height: 0px;
width: 0px;
overflow: hidden;
position: absolute;