简体   繁体   English

打开所有外部链接,并在除域之外的新标签页中打开

[英]Open all external links open in a new tab apart from a domain

I'm trying to open all external links on a site in a new window. 我正在尝试在新窗口中打开网站上的所有外部链接。 However on there are 2 versions of the site, eg a store and the main site. 但是,网站上有2个版本,例如商店和主站点。 So on the main site we might have links that go to http://store.example.com for example. 因此,在主站点上,我们可能具有指向http://store.example.com的链接。

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 any additional information would be brilliant. 我是JS / jQuery的新手,所以任何其他信息都很棒。

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
      }
   })
});

Are you able to edit the HTML to get a better hook for maybe a click event? 您是否可以编辑HTML,以更好地捕捉click事件? If i need to separate certain links between internal or external i will apply a rel value on the HTML element. 如果我需要分隔内部或外部之间的某些链接,我将在HTML元素上使用rel值。

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

Then in your javascript 然后在你的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');
        });
      }

    });

if you just want all links that don't match 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';
       }
}

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. 编辑:此外,您可以使用techfoobar的解决方案来触发链接点击。 That will help you with your websites performance. 这将帮助您提高网站性能。

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. 与techfoobar的回复一样,您可以构建一个域列表,该域应保留在同一窗口中打开。 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. 如果您只是直接进行indexOf()检查,则将跳过具有匹配子域但不匹配域的链接,但是如果要在href字符串中的任何位置匹配名称,则可以省略“ $”。

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. 在此示例中,所有转到google.com和stackoverflow.com的链接也将保留在现有页面中打开。

If you'd rather use an event handler on body than change the dom, I recommend something like this... 如果您想在主体上使用事件处理程序而不是更改dom,我建议使用类似的方法...

  // 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;
  });

This will do the trick for all external domains using PHP 这将使所有使用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
      }
   })
});

Building on Collin's answer in raw JS, which is very nice as it doesn't need Jquery (despite OP's question). 建立在原始JS的Collin答案的基础上,这非常好,因为它不需要Jquery(尽管有OP的问题)。 I'd amend it to have the ability to exclude domains other than the 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';
        }
    }        

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM