Open all external links open in a new tab apart fr

2019-03-19 20:29发布

问题:

I'm trying to open all external links on the site in a new window. However on there are 2 versions of the site. e.g a store and the main site. So on the main site we might have links that go to http://store.site.com for example.

I've got some code here which will allow me to open all the external links in a new window. However I'd like to be able to exclude certain domains. Like the one I've mentioned above.

Here is the code:

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

I'm new to JS / Jquery so as much information would be brilliant.

回答1:

For triggering the clicks programmatically, you 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
      }
   })
});


回答2:

Are you able to edit the HTML to get a better hook for maybe a click event? If i need to separate certain links between internal or external i will apply a rel value on 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 as you already have a ton of links, how 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');
        });
      }

    });


回答3:

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 manual but, if you don't want to deal with splitting strings and arrays, this is the solution. I'm sure this will help.

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



回答4:

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

This implementation should do what you want and there are minimal modifications 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 links going to google.com and stackoverflow.com will be left to open in the existing page as well.



回答5:

If you'd rather use an event handler on body than change the dom, I recommend something 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;
  });


回答6:

This will do the trick for all external 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
      }
   })
});