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

Aar*_*ley 35 html javascript clipboard jquery

我试图在不使用Flash的情况下复制到剪贴板,如果浏览器与javascript方法不兼容,我计划使用ZeroClipboard重新使用Flash .

我有一个按钮的onClick监听器,看起来像:

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

和输入字段如下:

<input type="text" name="Element To Be Copied" id="inputContainingTextToBeCopied" value="foo"/>
Run Code Online (Sandbox Code Playgroud)

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

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


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

Dan*_*ens 67

这是我的解决方案,不使用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);
}
Run Code Online (Sandbox Code Playgroud)
<!DOCTYPE html>
<html>
<head>
<title>Set Clipboard</title>
</head>
<body>
    <button onclick="setClipboard('foo loves bar')">Set Clipboard</button>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

  • 如果您需要保留换行符,一项改进是创建一个“textarea”而不是“input”,在我的情况下,该值来自隐藏的 &lt;pre&gt; (因此保留了换行符) (3认同)

Dav*_*ain 31

--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 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);
Run Code Online (Sandbox Code Playgroud)
#copy-me {
    display:none
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

  • 这是巨大的,只需将元素移出屏幕并使用 execCommand 函数复制它......检查底部的我的答案。 (2认同)

Aar*_*ley 17

感谢@DavidDomain的帮助,我找到了一种有点hacky但功能性的方法.

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

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

显示:在对js进行以下修改后添加了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';
}
Run Code Online (Sandbox Code Playgroud)

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


Tay*_*orS 9

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

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

脚本的作用是使用一个隐藏在屏幕一侧的输入,通过 CSS 或内联样式,然后快速选择它并运行复制命令。

function copyFunc() {
  var copyText = document.getElementById("copyInp");
  copyText.select();
  document.execCommand("copy"); //this function copies the text of the input with ID "copyInp"
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

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

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


小智 7

您可以简单地使用 opacity:0.00000000000001 隐藏输入标签,然后使用 javascript 将隐藏文本复制到剪贴板

function myFunction() {
  var copyText = document.getElementById("myInput");
  copyText.select();
  copyText.setSelectionRange(0, 99999)
  document.execCommand("copy");
  alert("Text copied successfully");
}
Run Code Online (Sandbox Code Playgroud)
<input type="text" value="===your text here===" id="myInput" style="opacity:0.00000000000001">
<button onclick="myFunction()">Copy</button>
Run Code Online (Sandbox Code Playgroud)


Din*_*h M 6

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

#copy-me {
    position: absolute;
    opacity: 0;
}
Run Code Online (Sandbox Code Playgroud)


小智 6

您可以window.navigator为此使用:

navigator.clipboard.writeText('this will be copied to the clipboard');
Run Code Online (Sandbox Code Playgroud)


Ric*_*ick 5

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>
Run Code Online (Sandbox Code Playgroud)