1

I'm trying to create a simple function that takes the textContent of a specific div element and copies it to the clipboard. But whenever I try to copy the text, I receive an error.

Am I missing something with Vue and his behavior with such actions?

HTML:

<div id="rgb">{{ RGB }}</div>
<button @click="copyColor('rgb')">Copy</button>

<div id="hex">{{ HEX }}</div>
<button @click="copyColor('hex')">Copy</button>

<div id="hsl">{{ HSL }}</div>
<button @click="copyColor('hsl')">Copy</button>

Javascript:

methods: {
    copyColor(id){
    var copyText = document.getElementById(id).textContent;
    navigator.clipboard.writeText(copyText);
   }
 },

Errors:

[Vue warn]: Unhandled error during execution of native event handler 
Uncaught TypeError: Cannot read properties of undefined (reading 'writeText')

Image of the error: https://i.stack.imgur.com/NQGmh.png

Thanks!

ChenBr
  • 1,671
  • 1
  • 7
  • 21
  • can you share the code in sandbox? – Nayeem M. Muzahid Jun 04 '22 at 13:38
  • @NayeemM.Muzahid It was complicated to move the whole code to a sandbox because it contains many unrelated components. I created a sandbox with the relevant code: [Link](https://codesandbox.io/s/delicate-sky-8bh7xx?file=/src/components/HelloWorld.vue). I also receive an error in the sandbox. – ChenBr Jun 04 '22 at 14:12
  • @ChenBr I am not sure what issue you are facing but the code you written initially is working fine. Here is the demo : https://jsfiddle.net/xbv732ep/ – Debug Diva Jun 04 '22 at 17:46
  • @ChenBr can you post the solution as an answer please, and mark it as the correct answer? – Popnoodles Jul 01 '23 at 02:10
  • @Popnoodles, Yes, no problem. Did it just know :) – ChenBr Jul 01 '23 at 15:10

2 Answers2

1

Well, it did not work the way you wanted to do it. Basically it has some security issue with navigator.clipboard.writeText() method but not sure about that.

for reference check this out: navigator.clipboard is undefined

Here is another way to do it. Hope this will solve the Copy To Clipboard issue.

copyToClipboard() {
  let textToCopy = document.getElementById("rgb").textContent;

  console.log(textToCopy);
  // text area method
  let textArea = document.createElement("textarea");
  textArea.value = textToCopy;
  textArea.style.position = "fixed";
  textArea.style.left = "-999999px";
  textArea.style.top = "-999999px";
  document.body.appendChild(textArea);
  textArea.focus();
  textArea.select();
  return new Promise((res, rej) => {
    document.execCommand("copy") ? res() : rej();
    textArea.remove();
  });
}
  • 1
    Thank you for the help. I was trying to create a clipboard functionality without using the ```textarea attribute```. I found a solution which I updated in the original question. – ChenBr Jun 04 '22 at 15:57
1

After many failed tries, I finally found a working solution. Important to note that it's a solution for Vue 3. If you're using Vue 2, you might want to checkout vue-clipboard2.

Installation of vue3-clipboard - Link

  1. Install vue3-clipboard by typing npm install --save @soerenmartius/vue3-clipboard

  2. Import VueClipboard into your app:

import { createApp } from 'vue'
import App from './App.vue'
import { VueClipboard } from '@soerenmartius/vue3-clipboard'

createApp(App).use(VueClipboard).mount('#app')
  1. Use the v-clipboard:copy="" handler.

Here's what my code looks like after finding the solution:

<div id="rgb">{{ RGB }}</div>
<button v-clipboard="RGB">Copy</button>

<div id="hex">{{ HEX }}</div>
<button v-clipboard="HEX">Copy</button>

<div id="hsl">{{ HSL }}</div>
<button v-clipboard="`[` + HSL + `]`">Copy</button>

I hope it helps anyone.

ChenBr
  • 1,671
  • 1
  • 7
  • 21