使用 execCommand (Javascript) 将隐藏文本复制到剪贴板
Posted
技术标签:
【中文标题】使用 execCommand (Javascript) 将隐藏文本复制到剪贴板【英文标题】:Using execCommand (Javascript) to copy hidden text to clipboard 【发布时间】:2015-10-14 02:37:03 【问题描述】:我正在尝试在不使用 Flash 的情况下复制到剪贴板,如果浏览器与 javascript 方法不兼容,我计划使用 ZeroClipboard 回退到 Flash。
我有一个按钮的 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"
都没有成功。两者都会导致按钮选择整个页面并将整个内容复制到用户的剪贴板。
我相对确信原因不是基于浏览器的,但以防万一,我正在 Mac OS X 10.10.4 上的 Chrome(版本 43.0.2357.134(64 位))上进行测试。
有没有一种方法可以在隐藏 的同时保持其可见性?或者如果不是我可以采取的替代路线?
我知道类似的问题,但没有一个能解决我的问题,要么是太旧,要么没有真正使用 Javascript,要么不适合特定的场景。 Here's a good answer 对于任何有类似但不太具体的问题的人。
【问题讨论】:
你试过 opacity: 0 吗? @DavidDomain 我刚刚尝试过,它可以工作,太棒了,谢谢!但不幸的是,它仍然会留下透明 div 并移动设计,如果没有更好的解决方案,我会继续这样做并将输入字段设置为 1px x 1px。如果你想回答我会很乐意接受,如果没有更好的出现。再次感谢! 如果你使用 jQuery 来 show() 输入,然后调用 copy,然后立即再次 hide() 呢? @pokkanome 我采取了与此非常相似的路线,我会尽快发布答案,谢谢! 我使用 style="position: absolute; top: -999px; left: -999px" 【参考方案1】:这是我不使用 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>
【讨论】:
它对我有用,丹,非常感谢。我搜索了这么多代码超过 2 小时,没有人为我工作。但你的代码很好。小而有效。再次感谢。 您好,我刚刚遇到了这个问题,几个小时以来一直在寻找这样的解决方案。如果没有 jQuery 的代码很好,那么这个脚本的头部是否需要任何外部链接/调用?因为现在我正在使用ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js 的google jQuery 文件,我是否需要参考其他文件才能使其正常工作?谢谢! 我的 sn-p 使用标准 Javascript 并且应该在现代网络浏览器中按原样工作。我会检查您的目标浏览器的execComand
功能的浏览器兼容性(大多数都支持它):developer.mozilla.org/en-US/docs/Web/API/Document/…
如果您需要保留换行符,一个改进是创建一个“textarea”而不是“input”,在我的情况下,值来自隐藏的 (因此保留了换行符)天哪,非常感谢。这完美地集成到我的代码中并且非常紧凑!【参考方案2】:
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>
【讨论】:
这是迄今为止最简单、最好的解决方案。 这是最简单最好的解决方案。 优秀的解决方案老兄。 我们赢了。谢谢【参考方案3】:--更新--
Document.execCommand()
[1] 在 Firefox 41 之前,需要在 user.js 首选项文件中启用剪贴板功能。请参阅Mozilla preferences for more information 的简要指南。如果不支持或启用该命令,则 execCommand 会引发异常而不是返回 false。在 Firefox 41 及更高版本中,剪贴板功能在任何能够弹出窗口(半可信脚本)的事件处理程序中默认启用。
因为Firefox version 41 Document.execCommand() 现在可以工作了。所以不再需要使用后备。
由于浏览器在剪贴板访问方面的行为似乎有所不同, 我花了一段时间才明白这一点。
它与您的解决方案非常相似,但不同之处在于创建一个临时元素并用输入 value
填充它。这样我们就可以将输入的display
属性设置为none
。
IE 也有一个解决方法,它使用window.clipboardData
。
Firefox 根本不允许我访问剪贴板。所以我不得不添加一个prompt
让用户手动复制输入值。当然prompt
很丑,但你可以只使用像窗口这样的模态框,它会做同样的事情。
由于这似乎是一件棘手的事情,我在 Win7(64 位) 并在
中进行了测试Chrome - 版本 43.0.2357.134 m
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>
【讨论】:
这是巨大的,只需将元素移出屏幕并使用 execCommand 函数将其复制...检查底部的答案。【参考方案4】:感谢@DavidDomain 的帮助,我找到了一种有点老套但实用的方法。
首先,我将输入方式移出屏幕并修改了一些属性,结果如下:
<input type="text" name="Element To Be Copied" id="inputContainingTextToBeCopied" value="foo" style="display:none; position: relative; left: -10000px;"/>
对js进行以下修改后添加display:none
之后,@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 复制,这在浏览器安全方面是有意义的,因为毫无疑问地访问剪贴板会有些风险。不过,所采取的方法具有相同的预期结果。
【讨论】:
【参考方案5】:我在这里有一个不太过时的解决方案:
使用此脚本,您可以复制数据。它比过去提供的脚本要小得多。
脚本的作用是使用隐藏在屏幕一侧的输入,使用 CSS 或内联样式,然后快速选择它并运行复制命令。
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>
对于 Bonus,我制作了一个小的剪贴板 API,它可以动态选择元素并使用 Contenteditable div 和动态变量从中检索文本:https://codepen.io/SkylerSpark/pen/OJJqxWX
另外,请参阅下面的 Ciprians Answer 关于使用新的 Permissions API 以用户允许的权限将文本直接发送到剪贴板,它不完全受支持,但它在最新的浏览器中可用(我知道它实际上适用于 chrome目前,但我还没有测试任何其他浏览器):https://***.com/a/58099014/11165703
【讨论】:
和我的想法一样,只是在屏幕上使用 css 隐藏输入元素 :) @aldrien.h 你知道如果你用 display: hidden 或类似的方式隐藏一个元素,就不能选择它吗?我希望你会。所以真的,除非你想通过使元素的每个部分都用透明颜色“隐藏”来添加更多的 CSS,否则你的想法是行不通的。 我的意思是,使用 css 在屏幕上隐藏,就像上面的样式一样,绝对位置在顶部和左侧具有负值,不显示:无,execCommand
将不适用于隐藏元素。 :)
实际上是@Dan Stevens 答案的副本,只是将样式放入元素而不是脚本中。
@VeenarM 这是你需要学习的东西,在***中,如果信息更可行,代码是否“相似”都没关系......我在这里添加的代码有数十亿份,但老实说,我不是抄写员,我自己写的 :P 而且我的剧本比 dans 短得多,不是为了竞争,而是事实。【参考方案6】:
您可以简单地使用 opacity:0.00000000000001 隐藏输入标签,然后使用 javascript 将隐藏的文本复制到剪贴板
function myFunction()
var copyText = document.getElementById("myInput");
copyText.select();
copyText.setSelectionRange(0, 99999)
document.execCommand("copy");
alert("Text copied successfully");
<input type="text" value="===your text here===" id="myInput" style="opacity:0.00000000000001">
<button onclick="myFunction()">Copy</button>
【讨论】:
Should you also make it have a width of 0 so it does not take up space?
【参考方案7】:
另一种适用于所有浏览器的解决方法是,您可以使用绝对位置将其不透明度设置为 0,而不是隐藏元素。
#copy-me
position: absolute;
opacity: 0;
【讨论】:
谢谢。这对我更有用,absolute
位置和-1000px
的解决方案top
和bottom
为我滚动。【参考方案8】:
您可以为此使用window.navigator
:
navigator.clipboard.writeText('this will be copied to the clipboard');
【讨论】:
这是最好和最现代的解决方案 兼容性:developer.mozilla.org/en-US/docs/Web/API/…【参考方案9】:对我有用的是:
<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");
);
【讨论】:
【参考方案10】:用这个怎么样: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 */
);
【讨论】:
这取决于最前沿的Permissions API,所以目前可能不会被广泛支持。很高兴看到浏览器开发人员正在寻找支持剪贴板的正确方法,因此我们不依赖本主题中的“黑客”。【参考方案11】:去做吧!
.blind
overflow: hidden;
position: absolute;
clip: rect(0 0 0 0);
width: 1px;
height: 1px;
margin: -1px;
<textarea id="copy" class="blind">
your copy text here!
</textarea>
copyClipboard(document.getElementById('copy'));
function copyClipboard(el)
el.select();
window.document.execCommand('copy');
https://gist.github.com/seunggabi/7ae53c100d647cb19c48047cff9b7019
【讨论】:
【参考方案12】:两种对我有用的方法:
方法一: 在这种方法中,输入元素最初是隐藏的,复制功能将其取消隐藏,选择并复制文本,然后再次隐藏它。
<script>
function copyLinkToClipboardViaHiddenField()
el = document.querySelector("#input");
el.style.display = "block";
var copyText = document.querySelector("#input");
copyText.select();
document.execCommand("copy");
el.style.display = "none";
document.getElementById("copylink").innerText = "copied OK!";
document.getElementById("copylink").href = "";
document.getElementById("copylink").style.color = "black";
document.getElementById("copylink").style.textDecoration = "none";
return false; // prevents click doing anything
</script>
<input id="input"
type="text"
style="display: none;"
value="https://www.example.org/ViaHiddenField"/>
<a href="javascript:void(0)"
onclick="return copyLinkToClipboardViaHiddenField()"
id="copylink"
style="text-decoration: underline;color: blue;">copy link ViaHiddenField</a>
方法 2: 在这种方法中,会创建一个新的输入元素并将其附加到文档正文的底部,复制其值,然后删除该元素。
<script>
function copyLinkToClipboardViaAppendElement()
el = document.createElement("input");
el.setAttribute('type', 'text');
el.setAttribute('value', "https://www.example.org/ViaAppendElement");
document.body.appendChild(el)
el.select();
console.log(el)
document.execCommand("copy");
el.parentNode.removeChild(el);
document.getElementById("copylink").innerText = "copied OK!";
document.getElementById("copylink").href = "";
document.getElementById("copylink").style.color = "black";
document.getElementById("copylink").style.textDecoration = "none";
return false; // prevents click doing anything;
</script>
<a href="javascript:void(0)"
onclick="return copyLinkToClipboardViaAppendElement()"
id="copylink"
style="text-decoration: underline;color: blue;">copy link ViaAppendElement</a>
【讨论】:
【参考方案13】:要将文本复制到剪贴板,它必须是可见的。 所以我创建了一个 input type=text 但设置样式 display:none 并使用 jquery 执行 show() 和 hide() 围绕复制。
<input type=text id='me' value='bla' style='display:none;'>
<button onclick='
$("#me").show();
var copyText = document.getElementById("me");
copyText.select();
copyText.setSelectionRange(0, 99999);
document.execCommand("copy");
$("#me").hide();
alert("Link copied to clipboard");
'></button>
【讨论】:
【参考方案14】:这是一个简单但很老套的答案,似乎对我有用。而不是使用display: none;
使用这个:
height: 0px;
width: 0px;
overflow: hidden;
position: absolute;
这允许选择,同时仍然隐藏文本区域并且不影响设计。
【讨论】:
我不会投反对票,因为这行得通。但是我会说,当你没有完全隐藏元素,或者至少将它移出屏幕时,它可能会导致选择错误......这很挑剔,虽然它在大多数情况下都可以工作,但现在你有一堆小 0pixel你看不到的屏幕上的元素。我知道这没有意义,但在极少数情况下,这可能是个坏主意,否则在正常使用时应该没问题。以上是关于使用 execCommand (Javascript) 将隐藏文本复制到剪贴板的主要内容,如果未能解决你的问题,请参考以下文章
所见即所得 - execCommand 使用 HTML5 正确更改字体和字体大小
html 使用execCommands编辑浏览器中的HTML内容
有啥比 document.execCommand 更好的吗?