【问题标题】:Open all external links open in a new tab apart from a domain打开除域之外的所有在新选项卡中打开的外部链接
【发布时间】:2012-08-17 18:23:23
【问题描述】:

我正在尝试在新窗口中打开网站上的所有外部链接。但是,该网站有 2 个版本,例如一家商店和主要网站。例如,在主站点上,我们可能有指向http://store.example.com 的链接。

我这里有一些代码可以让我在新窗口中打开所有外部链接。但是,我希望能够排除某些域。就像我上面提到的那样。

代码如下:

$(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"
         });
      }
   })
});

我是 JS / jQuery 的新手,所以任何额外的信息都会很棒。

【问题讨论】:

    标签: javascript jquery html url


    【解决方案1】:

    要以编程方式触发点击,您可以执行以下操作:

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

    【讨论】:

    • 技术,感谢您的回复。很抱歉,我看不出这里与页面顶部的内容有什么不同。您介意告诉我我在哪里添加了我认为不能用作外部域的域吗?
    • 查看我对排除列表逻辑的编辑(简单解决方案)。最初的答案是指出如何以编程方式触发链接点击(以便在新标签中打开它们)
    • 太棒了,谢谢。我现在已经在我的网站中实现了这个。只是做一些测试。当您指定域时,URL 是否为“excludeddomain/somethingthatcanchangehere”是否重要? (希望这是有道理的)。
    • 应该也可以,您可能希望将其(以及排除数组的内容)小写以使其在所有情况下都匹配
    • 可以加https&http吗?
    【解决方案2】:

    如果您只想要所有与您的域名不匹配的链接:

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

    【讨论】:

    • 我喜欢这个,因为它不需要 jquery
    【解决方案3】:

    您是否能够编辑 HTML 以获得更好的钩子来处理点击事件?如果我需要分隔内部或外部之间的某些链接,我将在 HTML 元素上应用一个 rel 值。

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

    然后在你的javascript中

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

    编辑:看到你已经有很多链接,这个怎么样..

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

    【讨论】:

    • 感谢您的回复。是的,我可以访问 HTML,但有数百个链接,您可以想象这可能需要一段时间。不过,我会记下您为将来的网站构建所做的方式,非常感谢。
    【解决方案4】:

    我想我会这样做:

        $(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"
               });
             }
           })
        });
    

    这有点手动,但是,如果您不想处理拆分字符串和数组,这就是解决方案。我相信这会有所帮助。

    编辑:除此之外,您还可以使用 techfoobar 的解决方案来触发链接点击。这将帮助您提高网站性能。

    【讨论】:

    • 很好,非常感谢。看起来这对我有用。很快就会更新答案。
    【解决方案5】:

    与 techfoobar 的回复一样,您可以构建一个应在同一窗口中打开的域列表。尽管使用正则表达式,但您可以以更健壮的方式进行操作。如果您只是直接执行 indexOf() 检查,您将跳过具有匹配子域但不匹配域的链接,但如果您想匹配 href 字符串中任何位置的名称,您可以省略“$”。

    这个实现应该做你想做的事,并且对你需要的代码做最少的修改。

    $(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"
             });
            }
          }
       })
    });
    

    在此示例中,所有指向 google.com 和 stackoverflow.com 的链接也将在现有页面中打开。

    【讨论】:

      【解决方案6】:

      如果您宁愿在 body 上使用事件处理程序而不是更改 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;
        });
      

      【讨论】:

        【解决方案7】:

        这将为所有使用 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
              }
           })
        });
        

        【讨论】:

        • 只需用location.hostname替换那个php,你就不再需要php了
        【解决方案8】:

        基于 Collin 在原始 JS 中的回答,这非常好,因为它不需要 Jquery(尽管有 OP 的问题)。我会修改它以排除当前主机名以外的域:

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

        【讨论】:

          【解决方案9】:

          抱歉线程死灵,谷歌把我带到这里。我遇到了类似的问题,最终这样解决:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-12-02
            • 1970-01-01
            • 1970-01-01
            • 2013-01-12
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多