Skip to content

Instantly share code, notes, and snippets.

@anselmh
Created July 24, 2013 12:12
Show Gist options
  • Select an option

  • Save anselmh/6069971 to your computer and use it in GitHub Desktop.

Select an option

Save anselmh/6069971 to your computer and use it in GitHub Desktop.
Open all external links (different hostname than current page) in new tab/window with plain vanilla JavaScript.
/**
* Open external links in new tab/window
*/
// All http:// links should open in new tab/window. Internal links are relative.
var anchors = document.querySelectorAll('a');
for (var i = 0; i < anchors.length; i++) {
if (anchors[i].host !== window.location.hostname) {
anchors[i].setAttribute('target', '_blank');
}
}
@jkphl

jkphl commented Jul 24, 2013

Copy link
Copy Markdown

Not sure if you should rely on the .host property of links – I had some issues with it in the past (don't remember the exact cirumstances though; might be some browsers not supporting it properly). Also, I'd recommend normalizing the anchors[i].host and window.location.hostname values (e.g. toLowerCase() or similar), as some browsers might mangle capitalization of domain names (for both the .host and the .hostname property). Just saying ... ;)

@anselmh

anselmh commented Jul 24, 2013

Copy link
Copy Markdown
Author

Thanks for your feedback! What would you recommend instead for not relying on .host? Had only read that all common browsers support it but a insight would be helpful.

@jkphl

jkphl commented Jul 24, 2013

Copy link
Copy Markdown

There might well be better solutions (and this one might have issues I'm not aware of yet), but this is a piece of code I use in my Google Analytics TYPO3 extension for detecting "same domain links":

var host                    = window.location.hostname.toLowerCase(),
regex                       = new RegExp('^(?:f|ht)tp(?:s)?\://(?:[^\@]\@)?([^:/]+)', 'im'),
match                       = url.match(regex),
domain                      = ((match ? match[1].toString() : ((url.indexOf(':') < 0) ? host : ''))).toLowerCase();

// Same domain
if (domain == host) {
    ...
}

where url is the href attribute value of the link. I remember I fiddled quite a while with this ... Btw. I just realize that I have no idea what would be the result with a link starting with "//", never tried this. ^^

@anselmh

anselmh commented Jul 24, 2013

Copy link
Copy Markdown
Author

Yeah, that's the point I recognized today. Having // links makes such RegEx things a complete mess. That's why I just used .host. Maybe I'll change that for testing. toLowerCase() is a good suggestion.

@jkphl

jkphl commented Jul 24, 2013

Copy link
Copy Markdown

Give me some time please. I will do some tests with the regex later today, then let you know again ... Should be no problem to match the // properly as well ... I will also be able to improve my TYPO3 extension this way. ;)

@jkphl

jkphl commented Jul 24, 2013

Copy link
Copy Markdown

Indeed, the regex didn't work with // links yet (and had a typo as well). I set up a codepen with updated regex, seems to work fine with quite a lot of different URL formats now. Did I miss a format?

http://codepen.io/jkphl/pen/dyqLu

@rajeevedmonds

Copy link
Copy Markdown

I've tested the codepen version, but it's not working correctly. I'm using it in an XML template in the following form.

<script type='text/javascript'>
/*<![CDATA[*/
function makeExternal(link) {
  var url      = link.getAttribute('href'),
  host         = window.location.hostname.toLowerCase(),
  regex        = new RegExp('^(?:(?:f|ht)tp(?:s)?\:)?//(?:[^\@]+\@)?([^:/]+)', 'im'),
  match        = url.match(regex),
  domain       = ((match ? match[1].toString() : ((url.indexOf(':') < 0) ? host : ''))).toLowerCase();

  // Same domain
  if (domain != host) {    
    link.setAttribute('target', '_blank');    
  }
}

for (var l = 0, links = document.querySelectorAll('a'), ll = links.length; l < ll; ++l ){
   makeExternal(links[l]); 
} 
/*]]>*/
</script>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment