2

I want to copy specific content from the page, rather than the HTML itself. And the execCommand method, is deprecated, I tried with useRef(), but no progress

How i solve this?

 const div = useRef(null);
 const [copySuccess, setCopySuccess] = useState(false);

 const copyToClipboard = () => {
   const html = div.current.innerHTML.trim();
   navigator.clipboard.writeText(html)
   setCopySuccess(true);
  };


 <div>
        {user.name && (
          <button
            type="submit"
            style={{
              margin-top: '30px',
              margin-bottom: '10px',
              height: '45px',
              width: '85px',
              background-color: '#1d71a5',
              color: '#fff',
              border: 'none',
              border-radius: '5px',
              font-size: '16px',
              cursor: 'pointer',
            }}
            onClick={copyToClipboard}
          >
            Copy
          </button>
        )}
        {copySuccess && (
          <div style={{ color: 'green' }}> ✔︎ Copy with Success! </div>
        )}
      </div>

I want to copy the signature email content

Refrence: https://vdt-email-signature.vercel.app

I tried to use the hook useRef, i tried to use this method :

const copyDivToClipboard = () => {
    const range = document.createRange()
    const selectedDiv = document.getElementById('generated-div')
    range?.selectNode(selectedDiv as Node)
    window?.getSelection()?.removeAllRanges() // clear current selection
    window?.getSelection()?.addRange(range) // to select text
    document.execCommand('copy')
    window?.getSelection()?.removeAllRanges() // to deselect
    alert('Message copied to clipboard!')
}

But is a deprecated method.

And so far I have no progress.

  • 2
    What's wrong with `navigator.clipboard.writeText(html)`? – Konrad Dec 02 '22 at 20:09
  • Does this answer your question? [How do I copy to the clipboard in JavaScript?](https://stackoverflow.com/questions/400212/how-do-i-copy-to-the-clipboard-in-javascript) – mikemaccana Dec 02 '22 at 20:18
  • Hey @Konrad, thats returns an HTML text content, and I want to select a content, as if it were the user selecting with the mouse and copying. if you see this reference: https://vdt-email-signature.vercel.app and click on button, you get the text html. And i want the content, not the text – Douglas Fernandes Dec 03 '22 at 14:31
  • So why do you use `innerHTML` instead of `textContent`? – Konrad Dec 03 '22 at 14:36
  • 'cause i only see this method in articles and stackoverflow. And it was for illustration of my problem. I dont know another method to get the content. And the object writeText just get the text, I want the content. – Douglas Fernandes Dec 03 '22 at 14:40
  • Hey @mikemaccana , I already see this on stackoverflow, thats topic doesn't solve my problem. The writeText method only get text, i want to select the content, and copy to paste in gmail signature. – Douglas Fernandes Dec 03 '22 at 15:08
  • @Konrad I solved the problem and reply my Issue. Thanks, because I had passed text and it was a type MIME html – Douglas Fernandes Dec 07 '22 at 01:13

3 Answers3

1

This way does what I want, but it is deprecated

 const div = useRef(null);
 const [copySuccess, setCopySuccess] = useState(false);

  const copyToClipboard = async () => {
    const html = div.current;
    const range = document.createRange();
    if (html) {
      range.selectNode(html);
    }

    const windowSelection = window.getSelection();

    if (windowSelection) {
      windowSelection.removeAllRanges();
      windowSelection.addRange(range);
    }

    try {
      const success = document.execCommand('copy');
      console.log(success ? 'Success' : 'Fail');
      setCopySuccess(true);
    } catch (e) {
      console.log('Fail', e);
    }
    setCopySuccess(true);
  }
1

I solved this problem, here we're go... The navigator.clipboard.write method expects a promise, and that's what helped me with this solution. but there are some points to be addressed, first that it expects an array, and the ClipboardItem constructor. Within them we have to specify what we want, in my case it was text/html, because I have images and texts. The code looked like this:

  const copyToClipboard = async () => {
    try {
    const html = div.current;

      const success = await navigator.clipboard.write([
        new ClipboardItem({
          'text/html': new Blob([html.innerHTML], {
            type: 'text/html',
          }),
        }),
      ]);
      setCopySuccess(true);
      return success;
    } catch (e) {
      console.log('Fail', e);
    }
    setCopySuccess(true);
  }
0

One easy way to achive this might be to add an id to the element you want to target, then inside your copyToClipboard function, use querySelector to get it.