将JavaScript变量的输出复制到剪贴板

110

我对JavaScript一无所知,但我成功地使用来自各种Stack Overflow答案的零散信息组装了这段代码。它可以正常工作,并通过警报框输出文档中所有选定复选框的数组。

function getSelectedCheckboxes(chkboxName) {
  var checkbx = [];
  var chkboxes = document.getElementsByName(chkboxName);
  var nr_chkboxes = chkboxes.length;
  for(var i=0; i<nr_chkboxes; i++) {
    if(chkboxes[i].type == 'checkbox' && chkboxes[i].checked == true) checkbx.push(chkboxes[i].value);
  }
  return checkbx;
}

我用以下方式来称呼它:

<button id="btn_test" type="button" >Check</button>
<script>
    document.getElementById('btn_test').onclick = function() {
        var checkedBoxes = getSelectedCheckboxes("my_id");
        alert(checkedBoxes);
    }
</script>

现在我想修改它,这样当我点击 btn_test 按钮时,输出数组 checkbx 将被复制到剪贴板中。我尝试添加:

checkbx = document.execCommand("copy");
或者
checkbx.execCommand("copy");

在函数结尾处,并像下面这样调用它:

<button id="btn_test" type="button" onclick="getSelectedCheckboxes('my_id')">Check</button>

但是它不起作用,没有数据被复制到剪贴板。


我怀疑你能否将一个原始的JS对象复制到剪贴板。.execCommand('copy')会复制页面上的选择内容(如果在用户偏好中允许)。你可以尝试将数组字符串化,然后用它填充文本区域,从文本区域中全选,然后使用execCommand进行复制。粘贴时,捕获事件,并将内容解析回数组。 - Teemu
好的,谢谢你指引我方向。我原本认为这可能不可能实现,因为似乎没有直接的搜索结果。所以我想我会尝试按照你建议的去做。 - harman
这可能是一个愚蠢的问题,但你会在哪里/如何粘贴原始JS对象? - Teemu
基本上这是为了一个WordPress的东西..我只是收集所有ID =某个ID的元素,然后将逗号分隔的ID粘贴到WordPress条件标签中。希望这有意义.. - harman
为了让意思更清晰,我正在收集所有被复选框选中的元素,而不是ID =某个ID的元素...;-) - harman
11个回答

147
function copyToClipboard(text) {
    var dummy = document.createElement("textarea");
    // to avoid breaking orgain page when copying more words
    // cant copy when adding below this code
    // dummy.style.display = 'none'
    document.body.appendChild(dummy);
    //Be careful if you use texarea. setAttribute('value', value), which works with "input" does not work with "textarea". – Eduard
    dummy.value = text;
    dummy.select();
    document.execCommand("copy");
    document.body.removeChild(dummy);
}
copyToClipboard('hello world')
copyToClipboard('hello\nworld')

1
如果你使用textarea,请小心。setAttribute('value', value) 不能与它一起使用。 - Eduard
如何复制带有\n的字符串? - qg_java_17137
3
有人能在 Chrome 上运行这个吗?我用的是 v70+,没有出现任何错误,但也无法复制。在 IE 中可以正常工作。 - ScottLenart
由于某些原因,我不得不使用.textContent而不是.value - mythofechelon
适用于Firefox 79.0、Chrome 84.0、IE 11和Edge 44(在Windows 10上)。 - NoJoshua
我尝试在React中使用您的代码,但似乎无法正常工作。插入了一个空值的Textarea,未复制并已删除。 - Cardoso

46

好的,我找到了一些时间并遵循了 Teemu 的建议,我最终获得了我想要的。

这是最终代码,供有兴趣的人参考。为了澄清,此代码获取特定 ID 的所有选中复选框,将它们输出到一个数组中,在此命名为 checkbx,然后将它们的唯一名称复制到剪贴板。

JavaScript 函数:

function getSelectedCheckboxes(chkboxName) {
  var checkbx = [];
  var chkboxes = document.getElementsByName(chkboxName);
  var nr_chkboxes = chkboxes.length;
  for(var i=0; i<nr_chkboxes; i++) {
    if(chkboxes[i].type == 'checkbox' && chkboxes[i].checked == true) checkbx.push(chkboxes[i].value);
  }
  checkbx.toString();

  // Create a dummy input to copy the string array inside it
  var dummy = document.createElement("input");

  // Add it to the document
  document.body.appendChild(dummy);

  // Set its ID
  dummy.setAttribute("id", "dummy_id");

  // Output the array into it
  document.getElementById("dummy_id").value=checkbx;

  // Select it
  dummy.select();

  // Copy its contents
  document.execCommand("copy");

  // Remove it as its not needed anymore
  document.body.removeChild(dummy);
}

并且它的HTML调用:

<button id="btn_test" type="button" onclick="getSelectedCheckboxes('ID_of_chkbxs_selected')">Copy</button>

11
不创建HTML元素,能否实现此操作?举个例子,当用户点击按钮或预先指定的元素时,我只想将一个字符串复制到用户的剪贴板中。 - VikingGoat
6
我建议使用 "textarea" 而不是 "input",这样你就可以复制换行符了。 - Telmo Trooper
1
document.execCommand() 已经被弃用 :( - Soubriquet
你不需要为元素设置id,然后通过id获取它。只需直接将值设置到元素中(例如 dummy.value=checkbox)。 - Roman

23

为了一般复制任何文本到剪贴板的目的,我编写了以下函数:

To 使用该函数,请传递要复制的文本作为参数。 这将在用户单击“复制”按钮时将文本复制到剪贴板。

代码如下:

function copyToClipboard(text) {
  var dummy = document.createElement("textarea");
  document.body.appendChild(dummy);
  dummy.value = text;
  dummy.select();
  document.execCommand("copy");
  document.body.removeChild(dummy);
}
function textToClipboard (text) {
    var dummy = document.createElement("textarea");
    document.body.appendChild(dummy);
    dummy.value = text;
    dummy.select();
    document.execCommand("copy");
    document.body.removeChild(dummy);
}

将该参数的值插入到新创建的<textarea>的值中,然后选择它,将其值复制到剪贴板,最后将其从文档中删除。


1
如果您使用textarea,请小心。setAttribute('value', value)可以用于"input",但无法用于"textarea"。 - Eduard

15

非常有用。我对它进行了修改,以将JavaScript变量的值复制到剪贴板:

function copyToClipboard(val){
    var dummy = document.createElement("input");
    dummy.style.display = 'none';
    document.body.appendChild(dummy);

    dummy.setAttribute("id", "dummy_id");
    document.getElementById("dummy_id").value=val;
    dummy.select();
    document.execCommand("copy");
    document.body.removeChild(dummy);
}

5
为了避免使用jQuery,将$(dummy).css('display','none');转换为dummy.style.display = 'none'; - Kardi Teknomo
4
谷歌浏览器需要显示虚拟卡片。因此我删除了一行代码,现在可以正常运行了,谢谢。 - shukshin.ivan
1
@shukshin.ivan 感谢您的建议!我最终将该行更改为:dummy.setAttribute("hidden", true);,因为 HTML 中隐藏属性的语法没有任何值,所以 true 可以是任何值。 - Jimmy Westberg
我还添加了一个简单的检查,以确定“value”是否为对象,如果是,则进行字符串化:if (typeof stuffToAddToClipboard === "object") { stuffToAddToClipboard = JSON.stringify(stuffToAddToClipboard); } - Jimmy Westberg
为什么要在虚拟元素上设置id,然后使用getElementById来设置值?这似乎是多余的工作,因为您已经有了对该元素的引用-您使用它来设置id。为什么? - Levesque
显示剩余4条评论

10

10

使用剪贴板 API

text = "HEllo World";
navigator.clipboard.writeText(text)

该功能适用于Chrome 66+、Edge 79+和Firefox 63+,但不支持I.E.

了解更多关于剪贴板 API 的信息,请访问MDN文档


1
哇,这个非常好用! - JL Gradley
1
在我的一台机器上,我只需要在本地工作的小任务变得容易多了。 - Keyslinger

8
我成功地将文本复制到剪贴板(不显示任何文本框)通过向 body 添加一个隐藏的 input 元素,即:

 function copy(txt){
  var cb = document.getElementById("cb");
  cb.value = txt;
  cb.style.display='block';
  cb.select();
  document.execCommand('copy');
  cb.style.display='none';
 }
<button onclick="copy('Hello Clipboard!')"> copy </button>
<input id="cb" type="text" hidden>


1
对我来说可以工作,但只有在输入框没有“hidden”属性的情况下才可以。在Chromium中,它强制使用样式"display: none !important",手动在脚本第4行设置"display: block"也无法覆盖该样式。 - II ARROWS
奇怪的是,这对我来说仍然失败了。相反,当我尝试粘贴时,它只会将剪贴板中的旧文本粘贴出来。这是已知的问题吗? - Destaq

8
现在有一个new(ish) API可以直接完成这个任务。它只适用于现代浏览器和HTTPS(以及本地主机),不支持IE11。
IE11有自己的API。
已接受答案中的解决方法可用于不安全的主机。
function copyToClipboard (text) {
  if (navigator.clipboard) { // default: modern asynchronous API
    return navigator.clipboard.writeText(text);
  } else if (window.clipboardData && window.clipboardData.setData) {     // for IE11
    window.clipboardData.setData('Text', text);
    return Promise.resolve();
  } else {
    // workaround: create dummy input
    const input = h('input', { type: 'text' });
    input.value = text;
    document.body.append(input);
    input.focus();
    input.select();
    document.execCommand('copy');
    input.remove();
    return Promise.resolve();
  }
}

注意:它使用Hyperscript创建输入元素(但应该很容易适应)。
没有必要使输入不可见,因为它添加和删除得非常快。而且即使使用一些聪明的方法将其隐藏,某些浏览器也会检测到并防止复制操作。

4

在撰写本文时,将元素设置为 display:none 不起作用。将元素的宽度和高度设置为0也不起作用。因此,元素的宽度至少必须为1px才能使其起作用。

以下示例在Chrome和Firefox中有效:

    const str = 'Copy me';
    const el = document.createElement("input");
    // Does not work:
    // dummy.style.display = "none";
    el.style.height = '0px';
    // Does not work:
    // el.style.width = '0px';
    el.style.width = '1px';
    document.body.appendChild(el);
    el.value = str;
    el.select();
    document.execCommand("copy");
    document.body.removeChild(el);

我想补充一下,我能理解为什么浏览器试图阻止这种hackish方法。最好公开显示您要复制到用户浏览器中的内容。但有时候我们无法更改设计要求。


1
我只想补充一点,如果有人想复制两个不同的输入到剪贴板。我也使用了将其放入变量的技术,然后将来自两个输入的变量文本放入文本区域中。
注意:下面的代码来自一个用户询问如何将多个用户输入复制到剪贴板。我修复了它以使其正常工作。因此,请期待一些旧式样式,例如使用var而不是let或const。我还建议为按钮使用addEventListener。

    function doCopy() {

        try{
            var unique = document.querySelectorAll('.unique');
            var msg ="";

            unique.forEach(function (unique) {
                msg+=unique.value;
            });

            var temp =document.createElement("textarea");
            var tempMsg = document.createTextNode(msg);
            temp.appendChild(tempMsg);

            document.body.appendChild(temp);
            temp.select();
            document.execCommand("copy");
            document.body.removeChild(temp);
            console.log("Success!")


        }
        catch(err) {

            console.log("There was an error copying");
        }
    }
<input type="text" class="unique" size="9" value="SESA / D-ID:" readonly/>
<input type="text" class="unique" size="18" value="">
<button id="copybtn" onclick="doCopy()"> Copy to clipboard </button>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接