惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

B
Blog RSS Feed
有赞技术团队
有赞技术团队
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
阮一峰的网络日志
阮一峰的网络日志
V
V2EX
Y
Y Combinator Blog
Jina AI
Jina AI
G
Google Developers Blog
Last Week in AI
Last Week in AI
博客园 - 叶小钗
H
Hackread – Cybersecurity News, Data Breaches, AI and More
L
LangChain Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
V
Visual Studio Blog
aimingoo的专栏
aimingoo的专栏
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
J
Java Code Geeks
Stack Overflow Blog
Stack Overflow Blog
IT之家
IT之家
The GitHub Blog
The GitHub Blog
D
Docker
量子位
罗磊的独立博客
腾讯CDC

Terence Eden’s Blog

Book Review: How to Build a Space Station by Jonathan Morrison Theatre Review: The School for Wives - at Riverside Studios How to get a DOI for your blog posts [RSS Club] Sorry for breaking your feed readers! Esoteric HTML - ismap vs CSS The expectations of privacy in driverless cars ActivityPub - How to send an updated user profile to Mastodon and the Fediverse [RSS Club] Sneak peek at new DOI functionality Put an AV test at the start of your slides ActivityPub - Is it worth defending against replay attacks and message/signature time skew? The purpose of DNS is to spread scams Book Review: The Passing of the Dragon and Other Stories by Ken Liu A reasonably practical guide to validating RFC 9421 HTTP Signatures for ActivityPub in PHP Book Review: ActivityPub by Evan Prodromou Review: Ruined Theatre's A Midsummer Night's Dream ActivityBot is the recipient of an NLnet grant! "iT woRKs BeTter in THe aPp!!" Book Review: The Infinite Sadness of Small Appliances by Glenn Dixon Gadget Review: Thermal Master P3 Macro Lens Theatre Review: Cats at Regent's Park Open Air Theatre Why do audience members choose specific shows at the Edinburgh Fringe? Death to px, long live ch! Book Review: An Immense World - How Animal Senses Reveal the Hidden Realms Around Us by Ed Yong Asymmetric Agents And then the men with guns tell you to do it anyway Thoughts on visiting the Edinburgh Fringe as a newbie Book Review: Slags by Emma Jane Unsworth Edinburgh Fringe: Target Audience Edinburgh Fringe: Stand-up Philosophy Edinburgh Fringe: Waiting for Wonka
A simple "copy this code" button in JavaScript
Terence Eden · 2026-08-29 · via Terence Eden’s Blog

Next to all the code samples on this blog is a little "copy" button. That makes it easier to grab any of the code I've shared.

The HTML and JS is delightfully simple:

Copied HTML to 📋 HTML<button
    onclick="navigator.clipboard.writeText(
        this.parentNode.getElementsByTagName('code')[0].textContent
    );" 
    title="Copy code"
>⧉</button>

The navigator.clipboard.writeText needs a user interaction to work - so it is tied to a click on the button.

It takes some plaintext content. But how to get that content? My code samples look like this:

Copied HTML to 📋 HTML<pre itemscope itemtype=https://schema.org/SoftwareSourceCode translate=no>
    <button onclick="navigator.clipboard.writeText( this.parentNode.getElementsByTagName('code')[0].textContent );">⧉</button>
    <span>
        <img alt height=32 src=html.svg width=32>
        <span itemprop=programmingLanguage> HTML</span>
    </span>
    <code itemprop=text>[…]</code>
</pre>

There are various ways I could get that <code> element:

  • Give it a unique ID (but that might clutter the code, or conflict with something else).
  • Use this.nextSibling.nextSibling (but that might not work if the layout changes).
  • Use this.lastChild.textContent (but, again, depends on the layout staying the same).
  • Select based on itemprop (could make the code a bit longer).
  • Complex filtering on a NodeList (urgh).

None of those are particularly bad per se, so I've chosen the method which makes most sense to me.

You can read more about my Classless Design, and how I use metadata to identify programming languages, including whether HTML's code blocks be translated.

To let people know that it has worked, I've added a little popover.

Every piece of code has it's own dialog element with a unique id:

Copied HTML to 📋 HTML<dialog
    id=pop
    popover=hint>Copied JS to 📋</dialog>

No JavaScript is required to show the popover when the copy button is pressed:

Copied HTML to 📋 HTML<button popovertarget=pop popovertargetaction=show>

Closing the the popover hint doesn't require JS; clicking outside it will dismiss it. But a little scrap of JS on the button's onclick will make it disappear after a few seconds:

Copied JavaScript to 📋 JavaScriptsetTimeout(
    function() {
        document.getElementById("pop").hidePopover();
    }, 
3000);

Positioning the popup so it is in proximity to the button also requires CSS - no JS.

Copied CSS to 📋 CSSdialog[popover] {
    inset: unset;
    position: absolute;
    padding: .5em;
}

If CSS isn't loaded, the default is to place it in the middle of the screen.

OK, that started out simple but got a bit more complex. Sorry!