I have two paragraphs of text, each has a "copy to clipboard" button, and each button has its own script. How can I combine these two button scripts into one?
HTML:
<p id="text1">Copy to clipboard 1</p>
<p id="text2">Copy to clipboard 2</p>
<div class="tooltip">
<button onclick="myFunction()" onmouseout="outFunc()">
<span class="tooltiptext" id="myBtn">Copy to clipboard</span>
Copy text
</button>
</div>
<div class="tooltip">
<button onclick="myFunction_1()" onmouseout="outFunc()">
<span class="tooltiptext" id="myBtn-1">Copy to clipboard</span>
Copy text
</button>
</div>
and JS:
<script>
function myFunction() {
navigator.clipboard.writeText(document.querySelector("#text1").innerText);
var tooltip = document.getElementById("myBtn");
tooltip.innerHTML = "Copied";
}
function outFunc() {
var tooltip = document.getElementById("myBtn");
tooltip.innerHTML = "Copy to clipboard";
}
</script>
<script>
function myFunction_1() {
navigator.clipboard.writeText(document.querySelector("#text2").innerText);
var tooltip = document.getElementById("myBtn-1");
tooltip.innerHTML = "Copied";
}
function outFunc() {
var tooltip = document.getElementById("myBtn-1");
tooltip.innerHTML = "Copy to clipboard";
}
</script>
>Solution :
To do what you require you can remove the dependency on incremental id and class attributes. Instead use the same class on elements with the same behaviour. You can use a data attribute on the button to denote the selector of the target element whose text should be copied.
Here’s a full example of how to achieve this. Also note the use of unobtrusie event listeners defined within JS, not in the HTML, and also a setTimeout() to return the original text after a delay instead of using mouseout().
const copyText = event => {
const button = event.currentTarget;
const selector = button.dataset.copyTarget;
const elementToCopy = document.querySelector(selector);
navigator.clipboard.writeText(elementToCopy.innerText);
button.querySelector('.tooltiptext').textContent = 'Copied';
setTimeout(() => button.querySelector('.tooltiptext').textContent = 'Copy to clipboard', 1000);
}
document.querySelectorAll('.copy').forEach(btn => {
btn.addEventListener('click', copyText);
});
<p id="text1">Copy to clipboard 1</p>
<p id="text2">Copy to clipboard 2</p>
<div class="tooltip">
<button type="button" class="copy" data-copy-target="#text1">
<span class="tooltiptext">Copy to clipboard</span>
Copy text
</button>
</div>
<div class="tooltip">
<button type="button" class="copy" data-copy-target="#text2">
<span class="tooltiptext">Copy to clipboard</span>
Copy text
</button>
</div>