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

Using execCommand (Javascript) to copy hidden text to clipboard

我正在尝试不使用 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 上测试 Chrome(版本 43.0.2357.134(64 位)) .4.

有没有一种方法可以在隐藏 时保持可见的功能?或者如果不是我可以选择的替代路线?


我知道类似的问题,none 解决了我的问题,要么是太老了,实际上没有使用 Javascript,要么是不适合特定情况。 Here's a good answer 对于遇到类似但不太具体的问题的任何人。

感谢@DavidDomain 的帮助,我找到了一个有点老套但实用的方法。

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

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

display:none是对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 进行复制,这在浏览器安全方面是有意义的,因为毫无疑问地访问剪贴板会有些风险。不过,所采用的方法具有相同的预期结果。

--更新--

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 is enabled by default in any event handler that is able to pop-up a window (semi-trusted scripts).

因为 Firefox version 41 Document.execCommand() 现在有效。所以不需要再使用回退。


由于浏览器在访问剪贴板时的行为似乎有所不同, 我花了一段时间才明白过来。

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

IE 还有一个解决方法,它使用 window.clipboardData.

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

由于这似乎是一个棘手的事情,我在 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>

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

这是一个简单但老套的答案,似乎对我有用。而不是使用 display: none; 使用这个:

height: 0px;
width: 0px;
overflow: hidden;
position: absolute;

这允许在隐藏文本区域且不影响设计的情况下进行选择。

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

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

脚本所做的是使用隐藏在屏幕一侧的输入 CSS 或 Inline-Styles,然后 select 快速运行它并运行副本命令。

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>

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

此外,请参阅下面的 Ciprians Answer,了解如何使用新的权限 API 以用户允许的权限将文本直接发送到剪贴板,它不完全受支持,但在最新的浏览器中可用(我知道它现在在 chrome 中确实有效,但我还没有测试过任何其他浏览器):

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>

对我有用的是:

<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");
});

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

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

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

就去做吧!

.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

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

两种对我有用的方法:

方法一: 在这种方法中,输入元素最初是隐藏的,复制功能取消隐藏它,选择并复制文本,然后再次隐藏它。

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

方法二: 在这种方法中,一个新的输入元素被创建并附加到文档主体的底部,它的值被复制,然后元素被删除。

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

要将文本复制到剪贴板,它必须是可见的。 所以我创建了一个输入 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> 

您可以为此使用 window.navigator

navigator.clipboard.writeText('this will be copied to the clipboard');