[ACCEPTED]-Open all external links open in a new tab apart from a domain-url

Accepted answer
Score: 18

For triggering the clicks programmatically, you 1 can do something like:

$(document).ready(function() {

   $("a[href^=http]").each(function(){

      // NEW - excluded domains list
      var excludes = [
         'excludeddomain1.com',
         'excludeddomain2.com',
         'excluded.subdomain.com'
      ];
      for(i=0; i<excludes.length; i++) {
         if(this.href.indexOf(excludes[i]) != -1) {
            return true; // continue each() with next link
         }
      }

      if(this.href.indexOf(location.hostname) == -1) {

           // attach a do-nothing event handler to ensure we can 'trigger' a click on this link
           $(this).click(function() { return true; }); 

           $(this).attr({
               target: "_blank",
               title: "Opens in a new window"
           });

           $(this).click(); // trigger it
      }
   })
});
Score: 4

if you just want all links that don't match 1 your domain name:

var all_links = document.querySelectorAll('a');
for (var i = 0; i < all_links.length; i++){
       var a = all_links[i];
       if(a.hostname != location.hostname) {
               a.rel = 'noopener';
               a.target = '_blank';
       }
}
Score: 1

Are you able to edit the HTML to get a better 6 hook for maybe a click event? If i need 5 to separate certain links between internal 4 or external i will apply a rel value on 3 the HTML element.

    <a href="URL" rel="external">Link</a>

Then in your javascript

    $('a[rel="external"]').click( function(event) {
     event.stopPropagation();
     window.open( $(this).attr('href') );
     return false;
    });

EDIT: seeing 2 as you already have a ton of links, how 1 about this..

    var a = new RegExp('http:\/\/store.blah.com');

    $('a').each(function() {

      if(a.test(this.href)) {
        $(this).click(function(event) {
         event.preventDefault();
         event.stopPropagation();
         window.open(this.href, '_blank');
        });
      }

    });
Score: 0

I think I would do it like this:

    $(document).ready(function() {
      $("a[href^=http]").each(function(){
         if(this.href.indexOf(location.hostname) == -1 && this.href.indexOf("store.domain.com") == -1 && this.href.indexOf("other.domain.rule") == -1) {
            $(this).attr({
               target: "_blank",
               title: "Opens in a new window"
           });
         }
       })
    });

It's kinda 6 manual but, if you don't want to deal with 5 splitting strings and arrays, this is the 4 solution. I'm sure this will help.

Edit: And 3 addition to this, you can use techfoobar's 2 solution for triggering link clicks. That 1 will help you with your websites performance.

Score: 0

Along the same lines as techfoobar's reply 14 you can build a list of domains that should 13 be left to open in the same window. You 12 can do it in a more robust way though using 11 regular expresions. If you just do a straight 10 indexOf() check you will skip links that 9 have matching subdomains but not matching 8 domains, although you can leave out the 7 '$' if you want to match the name anywhere 6 in the href string.

This implementation should 5 do what you want and there are minimal modifications 4 to the code you have needed.

$(document).ready(function() {
    //populate this list with whatever domain names you want, the 
    //$ sign matches the end of the string, only top level domains are affected
    var whiteList = [/google.com\/$/, /stackoverflow.com\/$/];

   $("a[href^=http]").each(function(){
      if(this.href.indexOf(location.hostname) == -1) {

        //check if the href of the current link matches any of our patterns
        var href = this.href;
        if(whiteList.filter(function(x){return x.test(href)}).length == 0) {

         $(this).attr({
            target: "_blank",
            title: "Opens in a new window"
         });
        }
      }
   })
});

With this example, all 3 links going to google.com and stackoverflow.com 2 will be left to open in the existing page 1 as well.

Score: 0

If you'd rather use an event handler on 2 body than change the dom, I recommend something 1 like this...

  // open external links in a new tab
  $('body').on('click','a',function(){
    var $a = $(this);
    var href = $a.attr('href');
    if (href.indexOf('/') == 0) return;  // ignore relative links
    var target = $a.attr('target') || "";
    if (target.length > 0) return; // ignore links with a target attribute already
    window.open(href, '_blank');  // open external links in a new tab
    return false;
  });
Score: 0

This will do the trick for all external 1 domains using PHP

$(document).ready(function() {
   $("a[href^=http]").each(function(){

      // NEW - excluded domains list
      var excludes = [
         '<?php echo $_SERVER['HTTP_HOST']; ?>'
      ];
      for(i=0; i<excludes.length; i++) {
         if(this.href.indexOf(excludes[i]) != -1) {
            return true; // continue each() with next link
         }
      }

      if(this.href.indexOf(location.hostname) == -1) {

           // attach a do-nothing event handler to ensure we can 'trigger' a click on this link
           $(this).click(function() { return true; }); 

           $(this).attr({
               target: "_blank",
               title: "Opens in a new window"
           });

           $(this).click(); // trigger it
      }
   })
});
Score: 0

Building on Collin's answer in raw JS, which 4 is very nice as it doesn't need Jquery (despite 3 OP's question). I'd amend it to have the 2 ability to exclude domains other than the 1 current hostname though:

    var all_links = document.querySelectorAll('a');
    var excludes = ['domain1.com','www.domain1.com','domain2.com'];
    for (var i = 0; i < all_links.length; i++){
        var a = all_links[i];
        var found = false; 
        for(j=0; j<excludes.length; j++) {
                if(a.href.includes(excludes[j])) {
                    found = true;
                    break;  
                }
        }    
        if (!found) {
            a.rel = 'noopener'; a.target = 'external';
        }
    }        
Score: 0

Sorry for thread necromancy, Google led 2 me here. I had a similar problem and ended 1 up solving it like this:

document.body.addEventListener('click', function (e) {
  if (e.target.tagName !== 'A') return;
  if (e.target.hostname === location.hostname) return;
  if(['stackoverflow.com','someothersite.com'].indexOf(e.target.hostname) !== -1) return; 
  e.preventDefault();
  window.open(e.target.href);
  return false;
});

More Related questions