Create A Copy Button For Code Blocks With Vanilla JavaScript
TODO
Look at replacing the function with this
function addCopyButtonTo(codeSelector, buttonParentSelector) {
const codeEl = document.querySelector(codeSelector)
const buttonParentEl = document.querySelector(buttonParentSelector)
const copyButton = document.createElement("button")
copyButton.innerHTML = "Copy"
copyButton.dataset.target = codeSelector
copyButton.addEventListener("click", async (event) => {
const elToCopy = document.querySelector(event.target.dataset.target)
console.log(elToCopy)
try {
let content
if (elToCopy.value) {
content = elToCopy.value
} else {
content = elToCopy.innerText
}
await navigator.clipboard.writeText(content)
event.target.innerHTML = "Copied"
} catch (err) {
event.target.innerHTML = "Error copying"
}
setTimeout((theButton) => {
event.target.innerHTML = "Copy"
}, 2000, event.target)
})
buttonParentEl.appendChild(copyButton)
}
Introduction
This is how I'm adding "Copy" buttons to code blocks.
The HTML
Everything starts with a
with a specific class that wraps the
tags that contain the code. In this case, I'm using code-copy-example
for this live example:
print("this is some code")
print("with a few lines")
The JavaScript
The button in the Output is added via JavaScript. It works by looking for any elements with the code-copy-example
class and dynamically adding the button to them with this JavaScript:
JavaScript
document.
The CSS
The last component of the setup is to position the button in the upper right corner with this CSS:
CSS
}
}
Wrapping Up
I really like this approach. It uses Progressive Enhancement1 so the Copy buttons don't show up unless JavaScript is working. That's compared to hard coding the buttons in the HTML where they would show up regardless of if the JavaScript to power them was working or not.
-- end of line --
Footnotes