使用 execCommand (Javascript) 将隐藏文本复制到剪贴板

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31593297/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 06:52:42  来源:igfitidea点击:

Using execCommand (Javascript) to copy hidden text to clipboard

javascriptjqueryhtmlclipboard

提问by Aaron Critchley

I'm trying to copy to clipboard without using Flash, I plan to fall back onto Flash with the use of ZeroClipboardif the browser is incompatible with the javascript approach.

我正在尝试在不使用 Flash 的情况下复制到剪贴板,如果浏览器与 javascript 方法不兼容,我计划使用ZeroClipboard回退到 Flash 。

I have an onClick listener for the button which looks like:

我有一个按钮的 onClick 侦听器,如下所示:

$(buttonWhereActionWillBeTriggered).click(function(){ 
    var copyDiv = document.getElementById(inputContainingTextToBeCopied);
    copyDiv.focus();
    document.execCommand('SelectAll');
    document.execCommand("Copy", false, null);
}

and an input field as follows:

和一个输入字段如下:

<input type="text" name="Element To Be Copied" id="inputContainingTextToBeCopied" value="foo"/>

This currently works as expected but the design requires that the field containing the text to be copied is invisible. I have tried both setting type="hidden"and style="display: none"neither of which have succeeded. Both resulting in the button selecting the whole page and copying the whole content to the user's clipboard.
I'm relatively confident the cause is not browser based but just incase, I am testing on Chrome (Version 43.0.2357.134 (64-bit)) on Mac OS X 10.10.4.

这目前按预期工作,但设计要求包含要复制的文本的字段不可见。我已经尝试了两种设置type="hidden"style="display: none"但都没有成功。两者都会导致按钮选择整个页面并将整个内容复制到用户的剪贴板。
我相对相信原因不是基于浏览器,而只是以防万一,我正在 Mac OS X 10.10.4 上的 Chrome(版本 43.0.2357.134(64 位))上进行测试。

Is there a way that I can maintain the functionality of when the < input> is visible whilst hiding it? or if not an alternate route I can take?

有没有办法可以在隐藏 <input> 的同时保持其可见的功能?或者如果不是我可以采取的替代路线?



I'm aware of similar questions, none of which address my problem, either from being too old, not actually using Javascript or not fitting the particular scenario. Here's a good answerfor anyone having similar, less specific issues.

我知道类似的问题,没有一个能解决我的问题,要么是太老了,要么是没有实际使用 Javascript,要么是不适合特定场景。对于任何有类似的、不太具体的问题的人来说,这是一个很好的答案

采纳答案by DavidDomain

--Update--

- 更新 -

Document.execCommand()

[1] Before Firefox 41, clipboard capability needed to be enabled in the user.js preference file. See A brief guide to Mozilla preferences for more information. If the command wasn't supported or enabled, execCommand was raising an exception instead of returning false.In Firefox 41 and later, clipboard capability are enabled by default in any event handler that is able to pop-up a window (semi-trusted scripts).

文档.execCommand()

[1] 在 Firefox 41 之前,需要在 user.js 首选项文件中启用剪贴板功能。有关详细信息,请参阅Mozilla 首选项简要指南。如果该命令不受支持或启用,则 execCommand 会引发异常而不是返回 false。在 Firefox 41 及更高版本中,默认情况下在任何能够弹出窗口的事件处理程序中启用剪贴板功能(半可信脚本)。

Since Firefox version 41Document.execCommand() now works. So no need to use a fallback anymore.

由于Firefox 版本 41Document.execCommand() 现在可以工作。所以不需要再使用回退了。



Since browsers seem to behave differently when it comes to the clipboard access, it took me a while to get my head around it.

由于浏览器在剪贴板访问方面的行为似乎有所不同,因此我花了一段时间才弄清楚。

It's pretty similar to your solution, but the difference is to create a temporary element and fill it with the input value. That way we can keep the input's displayproperty set to none.

它与您的解决方案非常相似,但不同之处在于创建一个临时元素并用 input 填充它value。这样我们就可以将输入的display属性设置为none

There is also a workaround for IEwhich uses window.clipboardData.

还有一种适用于IE的解决方法,它使用window.clipboardData.

Firefoxwould not let me access the clipboard at all. So i had to add a promptto let users manually copy the input value. Sure a promptis ugly, but you could just use a modal like window, which would do the same.

Firefox根本不允许我访问剪贴板。所以我不得不添加一个prompt让用户手动复制输入值。当然 aprompt是丑陋的,但你可以只使用像 window 这样的模式,它会做同样的事情。

Since this seems to be a knotty thing, i am on Win7 (64 bit)and tested in

由于这似乎是一件棘手的事情,因此我在Win7(64 位)上进行了测试

Chrome - Version 43.0.2357.134 m

铬 - 版本 43.0.2357.134 m

IE - Version 11.0.9600.17914

IE - 版本 11.0.9600.17914

and Firefox is irrelevant, because it would not let me access it anyway.

和 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>

回答by Dan Stevens

Here's my solution that doesn't use jQuery:

这是我不使用 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>

回答by Rick

2019 - was still looking for an answer without offscreen stuff.

2019 - 仍在寻找没有屏幕外内容的答案。

What I did is first change the input text field to type="text", copy the text and then change it back to type="hidden". That works well.

我所做的是首先将输入文本字段更改为 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>

回答by Aaron Critchley

Thanks to the help of @DavidDomain, I found a somewhat hacky, but functional approach.

感谢@DavidDomain 的帮助,我发现了一种有点笨拙但实用的方法。

Firstly, I moved the input way off screen and modified some properties, resulting in this:

首先,我将输入方式移出屏幕并修改了一些属性,结果如下:

<input type="text" name="Element To Be Copied" id="inputContainingTextToBeCopied" value="foo" style="display:none; position: relative; left: -10000px;"/>

display:none was added after the following modifications to the js

display:none 是在对js进行以下修改后添加的

After that, the comment from @Pokkanome let me into modifying the onClick function like so:

之后,@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';
}

I'm unsure if it's possible to copy from a hidden div using this method, which would make sense in terms of browser security as giving unquestioned access to the clipboard is going to be somewhat risky. The approach taken had the same intended result though.

我不确定是否可以使用这种方法从隐藏的 div 中复制,这在浏览器安全性方面是有意义的,因为毫无疑问地访问剪贴板会有一些风险。不过,所采取的方法具有相同的预期结果。

回答by Mister SirCode

I have a less outdated Solution here:

我这里有一个不太过时的解决方案:

Using this script, you can copy your data. its much smaller than the past scripts provided.

使用此脚本,您可以复制数据。它比过去提供的脚本小得多。

What the script does is use an Input that is hidden off the side of the Screen either with CSS or Inline-Styles, and then selects it quickly and runs the copy command.

该脚本的作用是使用一个隐藏在屏幕侧面的输入,通过 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>

For Bonus, I made a small Clipboard API that can select Elements Dynamically and retrieve Text from them using Contenteditable Divs and Dynamic Variables: https://codepen.io/SkylerSpark/pen/OJJqxWX

为了奖励,我制作了一个小的剪贴板 API,它可以使用 Contenteditable Divs 和动态变量动态选择元素并从中检索文本:https://codepen.io/SkylerSpark/pen/OJJqxWX

Also, go see Ciprians Answer below about using the new Permissions API to send text directly to the clipboard with permissions allowed by the user, its not fully supported, but its available in the latest browsers (I know it actually works in chrome right now, but I havent tested any other browsers): https://stackoverflow.com/a/58099014/11165703

另外,请参阅下面的 Ciprians Answer,了解使用新的 Permissions API 将文本直接发送到具有用户允许的权限的剪贴板,它不完全受支持,但它在最新的浏览器中可用(我知道它现在实际上适用于 chrome,但我还没有测试任何其他浏览器):https: //stackoverflow.com/a/58099014/11165703

回答by Dinesh M

An alternative workaround that works in all browser is, instead of hiding the element, you can set its opacity as 0 with absolute position.

适用于所有浏览器的替代解决方法是,您可以将其不透明度设置为具有绝对位置的 0,而不是隐藏元素。

#copy-me {
    position: absolute;
    opacity: 0;
}

回答by Douglas Lopes

What works to me was:

对我有用的是:

<div>
  <a class="copyBtn">Copy</a>
  <input class="d-none" value="teste">
</div>

and:

和:

$('.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");
});

回答by Ciprian

What about using this: https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/writeText

使用这个怎么样: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 */
});

回答by seunggabi

just do it!

去做就对了!

.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

https://gist.github.com/seunggabi/7ae53c100d647cb19c48047cff9b7019

回答by Mohamed Haseem

You can simply use opacity:0.00000000000001 to hide the input tag, then use javascript to copy the hidden text to clipboard

您可以简单地使用 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>