Reputation: 1066
I've been wondering how to copy a link with its HREF and text, for example we have an tag like this:
<a href="http://mysite.sample/?creds=creds">Quick Access to the website</a>
So basically I perfectly know how to copy something into the clipboard, my current work around consists in creating an invisible and small textarea where I put the text what I want to copy, then I select with js all the text inside the textarea and exec the copy command like this:
document.execCommand('copy');
Alright so I am able to copy raw text without issues, I can copy a link into my clipboard but once I paste it the link is just text and not an active link which can be clicked to go to its destination.
I know why is this happening, once I put the link into the textarea then it is not a link anymore but I don't know any other way to do this without breaking the link.
So, Once I copy the link I don't need to modify it with js or change the href or whatever, once I copy the link I want to paste it in a different page where I have no control over and I want my link to still be a link and not a simple text.
Any help would be appreciated. Due the project I'm working on I cannot relay on libraries for doing this I need some kind of native js workaround
This post is different to the post of How do I copy to the clipboard in JavaScript? I already know how to do that. What I want to know is how is posible to copy a link without losing it's link properties.
Upvotes: 14
Views: 19614
Reputation: 381
Using of document.execCommand('copy');
is deprecated now.
Here is an updated options according to actual browsers.
function copy() {
const link = document.querySelector("a");
navigator.clipboard
.write([
new ClipboardItem({
"text/html": new Blob([link.outerHTML], {
type: "text/html",
}),
"text/plain": new Blob([link.textContent], {
type: "text/plain",
}),
}),
])
.then(() => console.log("Copied"))
.catch((e) => console.log(e));
}
Upvotes: 0
Reputation: 56
I was going to leave this as a comment on Lux's answer, but don't have enough rep. For those stumbling upon this, to get the same functionality as you'd expect when selecting and copying rich text on a website, this article has you covered.
In short, its the same as Lux's approach, but you also have to include a "text/plain" blob when creating the ClipboardItem.
const richTextDiv = document.getElementById("richTextDiv");
const clipboardItem = new ClipboardItem({
"text/plain": new Blob(
[richTextDiv.innerText],
{ type: "text/plain" }
),
"text/html": new Blob(
[richTextDiv.outerHTML],
{ type: "text/html" }
),
});
navigator.clipboard.write([clipboardItem]);
Upvotes: 4
Reputation: 111
Here is another approach using the Clipboard interface (with step by step comments).
// Get the html from the portion of the page to copy (in this specific case your link)
const HTML=document.querySelector("a").outerHTML;
// Create a blob from the html
const TYPE="text/html";
const BLOB=new Blob([HTML], {type:TYPE});
// Copy the blob to the clipboard
navigator.clipboard.write([new ClipboardItem({[TYPE]: BLOB})])
// Optional but recommended. Check the result of the async operation
.then(
()=>console.log("copied"),
(err)=>console.log(err)
);
Please notice that the const HTML can be extracted from the document, as well as created on the fly. So you might do something like:
const HTML="<a href='http://mysite.sample/?creds=creds'>Quick Access to the website</a>";
Upvotes: 4
Reputation: 198294
A <textarea>
can only contain text. You need to copy an actual link. Try this:
const onClick = evt => {
const link = document.querySelector('a');
const range = document.createRange();
range.selectNode(link);
const selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
const successful = document.execCommand('copy');
};
document.querySelector('button').addEventListener('click', onClick);
This is an <a href="https://example.com">Example</a>.
<button>Copy</button>
EDIT: I noticed that I missed a huge discussion about... email? but I answered the question as asked - how to copy an actual link to clipboard.
Upvotes: 18