1

I have made a website that contains many different text parts that can be copied to the clipboard.

I used the script below for this.

Is there an alternative that doesn't require you to use an ID in the font tag? Because they are long pages of text and many text parts can be copied to the clipboard, it is annoying to use a new ID everytime. Everything is mixed up and additions are made regularly.

function copyElementText(id) {
  var text = document.getElementById(id).innerText;
  var elem = document.createElement("textarea");
  document.body.appendChild(elem);
  elem.value = text;
  elem.select();
  document.execCommand("copy");
  document.body.removeChild(elem);
}
Copy this text 4Copy this text 2
<font id="text1" onclick="copyElementText(this.id)">Copy this text 1</font>
<p>

  <font id="text2" onclick="copyElementText(this.id)">Copy this text 2</font>
  <p>

    <font id="text3" onclick="copyElementText(this.id)">Copy this text 3</font>
    <p>

      <font id="text4" onclick="copyElementText(this.id)">Copy this text 4</font>
      <p>
biberman
  • 5,606
  • 4
  • 11
  • 35
WJ496582
  • 921
  • 1
  • 8
  • 10
  • 2
    [font](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/font) has been obsoleted for a long time. For the question, see https://stackoverflow.com/questions/1687296/what-is-dom-event-delegation – Teemu Jul 02 '21 at 11:00
  • 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) – pilchard Jul 02 '21 at 11:02
  • No it does not. As I said I have multiple text parts that need to be copied to the clipboard. – WJ496582 Jul 02 '21 at 11:12
  • implement event delegation and add a `copyable` identifier/class? – pilchard Jul 02 '21 at 11:16

3 Answers3

2

2 differents way to do that:

function doCopy(el)
  {
  let elTxt            = document.createElement('textarea')
  elTxt.value          = el.textContent
  elTxt.style.height   = '0px'
  elTxt.style.width    = '0px'
  elTxt.style.opacity  = '0'
  document.body.appendChild(elTxt)
  elTxt.select()
  document.execCommand('copy') 
  document.body.removeChild(elTxt)
  }
// second way :
document.querySelectorAll('.toCopy').forEach(el=>el.onclick=_=>doCopy(el))
<p onclick="doCopy(this)">Copy this text 1</p>
<p onclick="doCopy(this)">Copy this text 2</p>

<!-- second way -->

<p class="toCopy">Copy this text 3</p>
<p class="toCopy">Copy this text 4</p>
Mister Jojo
  • 20,093
  • 6
  • 21
  • 40
2

you can also avoid creating a textarea to make your copy which allows to have a kind of animation on the execution of your copy

function doCopy(el)
  {
  el.classList.add('colorBGonClickCopy')  // ==> added
  let range = document.createRange()
  range.selectNode(el)
  getSelection().removeAllRanges()
  getSelection().addRange(range)
  document.execCommand('copy') 
  setTimeout(_=>
    { 
    getSelection().removeAllRanges() 
    el.classList.remove('colorBGonClickCopy') // ==> added 
    },500)
  }
// second way :
document.querySelectorAll('.toCopy').forEach(el=>el.onclick=_=>doCopy(el))
.colorBGonClickCopy::selection {
  background-color: #dc143c8f !important;   
  }
<p onclick="doCopy(this)">Copy this text 1</p>
<p onclick="doCopy(this)">Copy this text 2</p>

<!-- second way -->

<p class="toCopy">Copy this text 3</p>
<p class="toCopy">Copy this text 4</p>

You can can also do that, but this is not exactly the same as it change the entire element background color

function doCopy(el)
  {
  el.classList.add('colorBGonClickCopy')      // ==> added
  let range = document.createRange()
  range.selectNode(el)
  getSelection().removeAllRanges()
  getSelection().addRange(range)
  document.execCommand('copy') 
  setTimeout(_=>
    { 
    getSelection().removeAllRanges() 
    el.classList.remove('colorBGonClickCopy') // ==> added
    },900)
  }


// second way :
document.querySelectorAll('.toCopy').forEach(el=>el.onclick=_=>doCopy(el))
.colorBGonClickCopy::selection {
  background-color : transparent !important;
  }
.colorBGonClickCopy {
  animation        : 700ms bgAnim forwards;
  }
@keyframes bgAnim {
  0%   { background-color: #4606128f; }
  20%  { background-color: #dc143c8f; }
  80%  { background-color: #1449dc8f; }
  100% { background-color: #3cdc148f; }
  }
<p onclick="doCopy(this)">Copy this text 1</p>
<p onclick="doCopy(this)">Copy this text 2</p>

<!-- second way -->

<p class="toCopy">Copy this text 3</p>
<p class="toCopy">Copy this text 4</p>
Mister Jojo
  • 20,093
  • 6
  • 21
  • 40
0

You could use the event itself and its target to get the innerText:

onclick="copyElementText(event)"

Working example:

function copyElementText(event) {
  var text = event.target.innerText;
  var elem = document.createElement("textarea");
  document.body.appendChild(elem);
  elem.value = text;
  elem.select();
  document.execCommand("copy");
  document.body.removeChild(elem);
}
<p onclick="copyElementText(event)">Copy this text 1</p>
<p onclick="copyElementText(event)">Copy this text 2</p>
<p onclick="copyElementText(event)">Copy this text 3</p>
<p onclick="copyElementText(event)">Copy this text 4</p>

But it's better to move the inline event listener to the script.

Working example:

function copyElementText(event) {
  var text = event.target.innerText;
  var elem = document.createElement("textarea");
  document.body.appendChild(elem);
  elem.value = text;
  elem.select();
  document.execCommand("copy");
  document.body.removeChild(elem);
}

document.querySelectorAll('p').forEach(function(item) {
  item.addEventListener('click', copyElementText);
});
<p>Copy this text 1</p>
<p>Copy this text 2</p>
<p>Copy this text 3</p>
<p>Copy this text 4</p>
biberman
  • 5,606
  • 4
  • 11
  • 35