I'm fetching some html from the server which comes back as a string, but I need to insert a target='_blank' to all <a> tags within the html string. Is there a better or more efficient way to do this other than looping through the entire string to look for <a and then inserting target='_blank'?
5 Answers
There is the .replace method, using regex.
var string = "<a href='https://stackoverflow.com/'>Stack Overflow</a><br><a href='https://google.com/'>Google</a><br><a href='https://wikipedia.com'>Wikipedia</a>";
var newString = string.replace(/<a/g, "<a target='_blank'");
document.body.innerHTML = newString;
3 Comments
a already has a target attribute? Like _self for examplestring.replace(/<a target='_[^]*'/g, "<a target='_blank'");.string.replace(/<a target='_[^]*'/g, "<a target='_blank'");.First place the HTML into your page. Then immediately run code which modifies the DOM elements to include the needed attribute.
For example if you are placing the html into a container element with an id of container:
document.querySelectorAll('#container a').forEach(element => {
element.setAttribute('target', '_blank')
})
<div id="container">
<a href="http://google.com">Google</a>
<a href="http://wikipedia.com">Wikipedia</a>
</div>
Comments
//if you want to do it in a string;
response.replace(/<a/g, '<a target="_blank" ');
//if object (html)
//first append it to DOM
let container = document.querySelector(".container");
container.innerHTML = response;
container.querySelectorAll("a").forEach(el => el.setAttribute('target', '_blank'));
Comments
You could create an html element with the html code that comes back as a string, then getElementsByTagName('a') and finally set the target attribute to be "_blank", for example:
let string = `<ul><li><a href="http://example.com/1">Link 1</a></li><li><a href="http://example.com/2">Link 2</a></li><li><a href="http://example.com/3">Link 3</a></li></ul>`;
var el = document.createElement("html");
el.innerHTML = string;
let anchors = el.getElementsByTagName("a");
for (let anchor of anchors) {
anchor.setAttribute("target", "_blank");
}
console.log(el.innerHTML);
document.body.innerHTML = el.innerHTML;
Remember to use template literals ` to escape the double and single quotes of your html string.
Comments
Don't complicate htmlStrings more than they already are. Use this one liner after HTML has been rendered:
[...document.links].forEach(a => a.target = '_blank');
document.linksis a little known property that will collect all<a>into a HTML Collection.The bracket and spread operator
\[...\]wrapped around the HTML Collection converts it into a real Array..forEach()executes a callback function on each link within the Array.The callback function simply adds the
.targetproperty to each link and assigns them the value of"_blank".
Demo
[...document.links].forEach(a => a.target = '_blank');
// Just to check if each link is correctly modified
console.log([...document.links].map(a => a.outerHTML));
a {
font: 700 3vw/1.45 Verdana;
display: block;
width: max-content;
margin-bottom: 8px;
text-decoration: none
}
a:hover {
text-decoration: underline;
}
.as-console-wrapper {
width: 80%;
min-height: 100%;
margin-left: 20%;
}
<a href='example.com'>LINK</a>
<a href='example.com'>LINK</a>
<a href='example.com'>LINK</a>
<a href='example.com'>LINK</a>