<body>
<h1>"Copy bookmark link to clipboard" button</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure veritatis
expedita id. Reprehenderit cum in exercitationem tempore, a rem
praesentium iusto nam ducimus tempora totam minus, fuga, reiciendis
necessitatibus quisquam!
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusantium quis,
alias inventore distinctio laboriosam, quisquam nemo excepturi ipsum
necessitatibus quia, iusto illum cupiditate eius corporis labore provident
dignissimos? Iste, dignissimos.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusantium quis,
alias inventore distinctio laboriosam, quisquam nemo excepturi ipsum
necessitatibus quia, iusto illum cupiditate eius corporis labore provident
dignissimos? Iste, dignissimos.
</p>
<h2>First heading 2</h2>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nihil fugit,
distinctio ex incidunt sint sed unde, perferendis, quos modi nulla dolore
cumque delectus doloremque ab repudiandae earum nemo in adipisci.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusantium quis,
alias inventore distinctio laboriosam, quisquam nemo excepturi ipsum
necessitatibus quia, iusto illum cupiditate eius corporis labore provident
dignissimos? Iste, dignissimos.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusantium quis,
alias inventore distinctio laboriosam, quisquam nemo excepturi ipsum
necessitatibus quia, iusto illum cupiditate eius corporis labore provident
dignissimos? Iste, dignissimos.
</p>
<h3>A heading 3</h3>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptates harum
ipsum, expedita et reprehenderit error asperiores repudiandae aspernatur
eum optio. Illo unde odit, inventore praesentium et quia voluptatum
cupiditate similique?
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusantium quis,
alias inventore distinctio laboriosam, quisquam nemo excepturi ipsum
necessitatibus quia, iusto illum cupiditate eius corporis labore provident
dignissimos? Iste, dignissimos.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusantium quis,
alias inventore distinctio laboriosam, quisquam nemo excepturi ipsum
necessitatibus quia, iusto illum cupiditate eius corporis labore provident
dignissimos? Iste, dignissimos.
</p>
<h2>Second heading 2</h2>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nihil fugit,
distinctio ex incidunt sint sed unde, perferendis, quos modi nulla dolore
cumque delectus doloremque ab repudiandae earum nemo in adipisci.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusantium quis,
alias inventore distinctio laboriosam, quisquam nemo excepturi ipsum
necessitatibus quia, iusto illum cupiditate eius corporis labore provident
dignissimos? Iste, dignissimos.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusantium quis,
alias inventore distinctio laboriosam, quisquam nemo excepturi ipsum
necessitatibus quia, iusto illum cupiditate eius corporis labore provident
dignissimos? Iste, dignissimos.
</p>
<h3>Heading 3 again</h3>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptates harum
ipsum, expedita et reprehenderit error asperiores repudiandae aspernatur
eum optio. Illo unde odit, inventore praesentium et quia voluptatum
cupiditate similique?
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusantium quis,
alias inventore distinctio laboriosam, quisquam nemo excepturi ipsum
necessitatibus quia, iusto illum cupiditate eius corporis labore provident
dignissimos? Iste, dignissimos.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusantium quis,
alias inventore distinctio laboriosam, quisquam nemo excepturi ipsum
necessitatibus quia, iusto illum cupiditate eius corporis labore provident
dignissimos? Iste, dignissimos.
</p>
<h4>Heading 4</h4>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptates harum
ipsum, expedita et reprehenderit error asperiores repudiandae aspernatur
eum optio. Illo unde odit, inventore praesentium et quia voluptatum
cupiditate similique?
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusantium quis,
alias inventore distinctio laboriosam, quisquam nemo excepturi ipsum
necessitatibus quia, iusto illum cupiditate eius corporis labore provident
dignissimos? Iste, dignissimos.
</p>
<h5>Heading 5</h5>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptates harum
ipsum, expedita et reprehenderit error asperiores repudiandae aspernatur
eum optio. Illo unde odit, inventore praesentium et quia voluptatum
cupiditate similique?
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusantium quis,
alias inventore distinctio laboriosam, quisquam nemo excepturi ipsum
necessitatibus quia, iusto illum cupiditate eius corporis labore provident
dignissimos? Iste, dignissimos.
</p>
<h6>Heading 6</h6>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptates harum
ipsum, expedita et reprehenderit error asperiores repudiandae aspernatur
eum optio. Illo unde odit, inventore praesentium et quia voluptatum
cupiditate similique?
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusantium quis,
alias inventore distinctio laboriosam, quisquam nemo excepturi ipsum
necessitatibus quia, iusto illum cupiditate eius corporis labore provident
dignissimos? Iste, dignissimos.
</p>
<div id="snackbar">Link copied to clipboard</div>
@import url("https://fonts.googleapis.com/css2?family=Merriweather:wght@700&family=Poppins&display=swap");
body {
margin: 0 auto;
max-width: 600px;
font-family: Poppins, sans-serif;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: Merriweather, serif;
font-weight: bold;
display: flex;
align-items: center;
}
:is(h2, h3, h4, h5, h6) button {
text-decoration: none;
color: #767676;
margin: 0 0.25em;
padding: 0.1em;
font: inherit;
font-size: 0.8em;
transition: color 0.2s ease-in-out;
}
:is(h2, h3, h4, h5, h6) button:hover {
color: rgb(27, 27, 252);
}
/* Position it at the top and in the middle of the screen */
#snackbar {
position: fixed;
z-index: 1;
top: 0;
left: 50%;
min-width: 250px;
margin-left: -125px;
background-color: #333;
color: #fff;
text-align: center;
border-radius: 5px;
padding: 16px;
transform: translateY(-10px);
opacity: 0;
}
let headings = document.querySelectorAll("h2, h3, h4, h5, h6");
let snackbarTimeout;
// we do this to exclude the text fragment
const currentURL = `${window.location.protocol}//${window.location.host}${window.location.pathname}`;
headings.forEach((heading) => {
let slug = slugify(heading.innerText);
heading.setAttribute("id", slug);
const bookmarkBtn = document.createElement("button");
bookmarkBtn.innerText = "#";
bookmarkBtn.setAttribute("data-href", `${currentURL}#${slug}`);
bookmarkBtn.addEventListener("click", copyLink);
heading.append(bookmarkBtn);
});
/**
* Produces a slug from the text provided that can be used as an URL fragment. Does it the same as GitHub.
*
* @param {string} text - The text to slugify
* @returns {string} The slug.
*/
function slugify(text) {
// Anything that is an unwanted punctuation character
const PUNCTUATION_REGEXP = /[^\p{L}\p{M}\p{N}\p{Pc}\- ]/gu;
let slug = text.trim().toLowerCase();
slug = slug.replace(PUNCTUATION_REGEXP, "").replace(/ /g, "-");
return slug;
}
async function copyLink(event) {
const button = event.srcElement;
let text = button.getAttribute("data-href");
await navigator.clipboard.writeText(text);
showSnackbar();
}
function showSnackbar() {
let snackbar = document.getElementById("snackbar");
let fadeIn = snackbar
.animate(
[
{ opacity: 1, offset: 0.1 },
{ opacity: 1, offset: 0.8 },
{ opacity: 0, offset: 1 }
],
{
duration: 3000
}
)
.play();
let move = snackbar
.animate(
[
{ transform: "translateY(20px)", offset: 0.2 },
{ transform: "translateY(20px)", offset: 0.8 },
{ transform: "translateY(-10px)", offset: 1 }
],
{
duration: 3000
}
)
.play();
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.