开发者问题收集

javascript 将元素连同所有样式复制到剪贴板

2018-02-01
11547

我正在尝试将 div 复制到剪贴板。该 div 有几种样式,包括 背景 。我编写了一个脚本来将 div 复制到剪贴板,但我不知道如何设置背景。

我见过这种做法,但我记不清怎么做了。

如能得到任何帮助,我将不胜感激。


这是我得到的结果:

function executeCopy(text) {
    var copyDiv = document.createElement('div');
    copyDiv.contentEditable = true;
    document.body.appendChild(copyDiv);
    copyDiv.innerHTML = text;
    copyDiv.unselectable = "off";
    copyDiv.focus();
    document.execCommand('SelectAll');
    document.execCommand("Copy", false, null);
    document.body.removeChild(copyDiv);
}
#foo {
  background-color: red;
  font-family: cursive;
}
<div id="foo">Test</div>
<button onclick="executeCopy(document.getElementById('foo').innerHTML);">Copy</button>
3个回答

您可以尝试以下 fiddle。它适用于所有文本样式,并且可以与 MS Word 和 Pages 互操作(我刚刚测试过)。

代码非常简单,所以我不会深入探讨它,但如果您愿意,请随时向我提问。:)

const copyWithStyle = ( element ) => {

    const doc = document;
    const text = doc.getElementById( element );
    let range;
    let selection;

    if( doc.body.createTextRange ) {

        range = doc.body.createTextRange();
        range.moveToElement( text );
        range.select();

    } else if ( window.getSelection ) {

        selection = window.getSelection();

        range = doc.createRange();
        range.selectNodeContents( text );

        selection.removeAllRanges();
        selection.addRange( range );

    }

    document.execCommand( 'copy' );
    window.getSelection().removeAllRanges();
    document.getElementById( 'clickMe' ).value = 'Copied to clipboard!';

}

https://jsfiddle.net/aypdg3kL/

来自 JSFiddle 中的示例

HTML

<div id="text" style="color:red">
    <i>Hello</i> world!
</div>
<input id="btn" onclick="CopyToClipboard('text')" type="button" value="Copy" />

JS

function CopyToClipboard(element) {

        var doc = document
        , text = doc.getElementById(element)
        , range, selection;
    
    if (doc.body.createTextRange)
    {
        range = doc.body.createTextRange();
        range.moveToElementText(text);
        range.select();
    } 
    
    else if (window.getSelection)
    {
        selection = window.getSelection();        
        range = doc.createRange();
        range.selectNodeContents(text);
        selection.removeAllRanges();
        selection.addRange(range);
    }
    document.execCommand('copy');
    window.getSelection().removeAllRanges();
    document.getElementById("btn").value="Copied";
}
weirdpanda
2018-02-01

@weirdpanda 的优秀示例改编为现代 HTML API,您将获得以下结果:如果您运行示例并单击“复制”按钮并粘贴到 Excel 等电子表格程序中,您将获得相同的米灰色表格(“2.0”可能毫无帮助地呈现为“2”🙃)。

如果您将其放在 HTML 文件中并通过纯 HTTP 提供它,它将继续起作用 - 但需要注意的是,为了进行准确的测试,您必须将其托管在非 localhost HTTP URL 上,因为您的浏览器可能会为 localhost 提供安全上下文。

document.querySelector("button").onclick = () => {
  const target = document.querySelector("table");
  copyElement(target);
};

function copyElement(target) {
  const range = document.createRange();

  range.setStart(target, 0);
  range.setEndAfter(target);
  window.getSelection()?.removeAllRanges();
  window.getSelection()?.addRange(range);

  document.execCommand("copy");
  
  window.getSelection()?.removeAllRanges();
};
table {
  border: 1px solid black;
  border-collapse: collapse;
}
thead {
  background-color: gray;
  font-weight: bold;
}
tbody tr:nth-child(even) {
  background-color: lightgray;
}
tbody tr:nth-child(odd) {
  background-color: beige;
}
td {
  border: 1px solid black;
}
<button>Copy</button>

<table>
  <thead>
    <tr>
      <td>Name</td>
      <td>Type</td>
    </tr>
  </thead>
  <tbody>
    <tr><td>Murderbot</td><td>SecUnit</td></tr>
    <tr><td>ART</td><td>Research transport</td></tr>
    <tr><td>Amena</td><td>Human</td></tr>
    <tr><td>Tlacy</td><td>Augmented human</td></tr>
    <tr><td>2.0</td><td>Sentient virus</td></tr>
  </tbody>
</table>
Ahmed Fasih
2023-11-15

已接受的答案实现在 2024 年存在跨浏览器兼容性问题。

Uncaught (in promise) TypeError: Failed to execute 'selectNodeContents' on 'Range': parameter 1 is not of type 'Node'.
    at copyElementToClipboard

这是由以下行引起的: range.selectNodeContents(text);

使用 moveToElementText 是更安全、更正确的选择(修复了该问题):

function copyElementToClipboard(element) {
        let range;
        let selection;

        if (!element) {
          console.error("No element to copy");
          return;
        }

        if (document.body.createTextRange) {
          range = document.body.createTextRange();
          // correct method for text range
          range.moveToElementText(element);
          range.select();
        } else if (window.getSelection) {
          selection = window.getSelection();

          range = document.createRange();
          // ensuring textElement is passed correctly
          range.selectNodeContents(element);

          selection.removeAllRanges();
          selection.addRange(range);
        }

        try {
          document.execCommand("copy");
        } catch (err) {
          console.error("Unable to copy text: ", err);
        } finally {
          if (selection) {
            selection.removeAllRanges();
          }
        }
      }
kyr0
2024-05-29