复制到剪贴板包括目标元素的父元素

Copy to clipboard is including parent of targeted element

编辑 - 附加信息:

简化的沙箱 - https://codesandbox.io/s/stupefied-leftpad-k6eek

演示:https://imgur.com/a/SDWTQno

Firefox 似乎没有出现问题,但 chrome 和其他浏览器


我有一个 div 呈现模板(在上面 link 中进行了简化),它连接到一个按钮,该按钮调用一个复制到剪贴板的函数。

然而,当将复制的内容粘贴到剪贴板时,内容居中,进一步检查后,容器 div 样式({ display: 'flex', margin: '0 auto', justifyContent: 'center' })也包含在所选内容中。

如何从副本中排除父 div,它应该 以文字模板中的 html 代码为目标(最好是什么我按 ID 定位 - #signature-preview-workspace,因此不应该居中?

提前致谢

尝试使用 ref 而不是直接文档搜索。

const copyTextToClipboard = el => {
  const range = document.createRange(0);
  range.selectNode(el);
  window.getSelection().removeAllRanges();
  window.getSelection().addRange(range);
  document.execCommand("copy");
  window.getSelection().removeAllRanges();
};

const App = () => {
  const ref = React.useRef();

  const handleCopyClick = React.useCallback(() => {
    copyTextToClipboard(
      ref.current.querySelector("#signature-preview-workspace")
    );
  }, [ref]);

  return (
    <div id="App">
      <div
        ref={ref}
        style={{ display: "flex", margin: "0 auto", justifyContent: "center" }}
        dangerouslySetInnerHTML={{
          __html: `
            <!DOCTYPE html>
            <html>
              <body style="margin:0;padding:0;">
                <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
                <table id="signature-preview-workspace" cellpadding="0" cellspacing="0">
                  <tbody>
                    <tr>
                      <td>Contents here...</td>
                    </tr>
                  </tbody>
                </table>
              </body>
            </html>
          `
        }}
      />

      <div>
        <button onClick={handleCopyClick}>Copy text above</button>
      </div>

      <textarea placeholder="Paste copied..." />
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById("root"));
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>

<div id="root"></div>

你还有一个问题。您将 p 用作 tr 的子项,这是不正确的,会导致复制空文本。将 p 更改为 td

抱歉,我完全误解了您要查找的内容。我以为您想要删除 所有 样式..

似乎解决这个问题的方法只是将要复制的 "template" 包装在 div 中,而不对其应用任何样式..

这是Chrome中的一个demo using Gmail..

const { useRef, useCallback } = React;
const { render } = ReactDOM;

function App() {
  const ref = useRef();

  const copyTextToClipboard = el => {
    let range = document.createRange(0);
    range.selectNode(el);
    window.getSelection().removeAllRanges();
    window.getSelection().addRange(range);
    document.execCommand("copy");
    window.getSelection().removeAllRanges();
  };

  const handleCopyClick = useCallback(() => {
    copyTextToClipboard(
      ref.current.querySelector("#signature-preview-workspace")
    );
  }, [ref]);

  return (
    <div>
      <div
        ref={ref}
        style={{ display: "flex", margin: "0 auto", justifyContent: "center" }}
      >
        <div
          dangerouslySetInnerHTML={{
            __html: `
            <!DOCTYPE html>
            <html>
              <body style="margin:0;padding:0;">
                <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
                <table id="signature-preview-workspace" cellpadding="0" cellspacing="0">
                  <tbody>
                    <tr>
                      <td style="color: red;">Contents here...</td>
                    </tr>
                  </tbody>
                </table>
              </body>
            </html>
          `
          }}
        />
      </div>

      <button onClick={() => handleCopyClick()}>Copy</button>
    </div>
  );
}

render(<App />, document.getElementById("root"));
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>

<div id="root"></div>