15

I need to write a method that takes a String and parses it for links (a href). If it finds a link it should add target="_blank" to the link, if it is not already there.

Example: The Inputstring "

 <a href="www.google.com">Google</a> and <a href="www.yahoo.com"> target="_blank">Yahoo</a> are search engines

... should result in the output String

<a href="www.google.com" target="_blank">Google</a> and <a href="www.yahoo.com" target="_blank">Yahoo</a> are search engines

Any idea how to realize this?

4
  • 3
    just replace <a by <a target="_blank" Commented Jul 25, 2011 at 22:10
  • do you have to retrieve <a>s as strings? can you get them as elements with js? Commented Jul 25, 2011 at 22:11
  • unfortunately yes. There is no way to get them via DOM Commented Jul 25, 2011 at 22:12
  • @Paul why can't you access them via the dom? Commented Jul 25, 2011 at 22:21

5 Answers 5

28

Not very difficult with plain js.

var links = document.getElementsByTagName('a');
var len = links.length;

for(var i=0; i<len; i++)
{
   links[i].target = "_blank";
}
Sign up to request clarification or add additional context in comments.

Comments

10

Fraught with problems but usable with plain JavaScript:

function addBlankTargets(s) {
  return (""+s).replace(/<a\s+href=/gi, '<a target="_blank" href=');
}

Or with jQuery:

function addBlankTargets(s) {
  var p = $('<p>' + s + '</p>');
  p.find('a').attr('target', '_blank');
  return p.html();
}
var s = '<a href="www.google.com">Google</a> and '
      + '<a href="www.yahoo.com">Yahoo</a> '
      + 'are search engines.';
var x = addBlankTargets(s);
x; // => '<a href="www.google.com" target="_blank">Google</a> and
   //     <a href="www.yahoo.com" target="_blank">Yahoo</a>
   //     are search engines.'

2 Comments

The jQuery solution sounds good but I'm an absolute beginner in JavaScript. So, after I have the Strings in x (an Array I assume) how can I combine them back to a string?
@Paul: I updated my jQuery answer for completeness, see if that works for you. Basically, in jQuery, to get the "outer HTML" you must first wrap the items in another element and get its inner HTML.
2

If you are targeting at modern browsers, instead of manipulating a string containing HTML and having to handle all the many special cases, you can transform the string into DOM. At this point manipulating the DOM is trivial and you can then convert it back to a serialised string.

function decorateRichText(html) {
  const domParser = new DOMParser()
  const document = domParser.parseFromString(html, `text/html`)
  const serializer = new XMLSerializer()

  // Handles external links
  const links = document.querySelectorAll(`a`)

  links.forEach((link) => {
    if (link.href) {
      if (isExternalUrl(link.href)) {
        link.target = `_blank`
        link.rel = `noopener noreferrer`
      }
    }
  })

  return serializer.serializeToString(document)
}

Leave the browser JS engine do the heavy stuff and remember: code that you don't write is code you have not to debug :-)

Comments

0

You can use jQuery to parse the element, add the attribute, and then read out the HTML, like so:

 var addTarget = function(input) {
   return $('<span>' + input + '</span>').find('a').attr('target', '_blank').html();
 };

 console.log(addTarget('<a href="www.google.com">Google</a>'));

Comments

0

in two lines

var links = document.getElementsByTagName('a');
for(i in links)
    links[i].target=="_blank"?links[i].style.color="#f0f" : links[i].style.color ='#0f0'

jsfiddle

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.