打开除域之外的新选项卡中打开的所有外部链接

时间:2012-08-22 10:35:39

标签: javascript jquery html url

我正在尝试在新窗口中打开网站上的所有外部链接。但是,该网站有2个版本。例如商店和主要网站。因此,在主站点上,我们可能会有到http://store.site.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的新手,所以很多信息都很棒。

9 个答案:

答案 0 :(得分:12)

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

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

答案 1 :(得分:1)

您是否可以编辑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');
        });
      }

    });

答案 2 :(得分:0)

我想我会这样做:

    $(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的解决方案来触发链接点击。这将有助于您的网站性能。

答案 3 :(得分:0)

与techfoobar的回复一样,您可以构建一个应该在同一窗口中打开的域列表。您可以使用常规表达式以更强大的方式执行此操作。如果您只是直接进行indexOf()检查,您将跳过具有匹配子域但不匹配域的链接,尽管您可以忽略&#39; $&#39;如果你想在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的链接也将在现有页面中打开。

答案 4 :(得分:0)

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

答案 5 :(得分:0)

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

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

基于原始JS中Collin的答案,这非常好,因为它不需要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';
        }
    }        

答案 8 :(得分:0)

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

    public class LocationMoveAnim {

        public static void startAnimation(final Marker marker, final GoogleMap googleMap, final LatLng startPosition,
                                         final LatLng endPosition,final GoogleMap.CancelableCallback callback) {
          ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
          int duration = 500;
          valueAnimator.setDuration(duration);
          final LatLngInterpolatorNew latLngInterpolator = new LatLngInterpolatorNew.LinearFixed();
          valueAnimator.setInterpolator(new LinearInterpolator());
          valueAnimator.addUpdateListener(valueAnimator1 -> {
            float v = valueAnimator1.getAnimatedFraction();
            LatLng newPos = latLngInterpolator.interpolate(v, startPosition, endPosition);
            marker.setPosition(newPos);
            marker.setAnchor(0.5f, 0.5f);
            marker.setRotation((float) bearingBetweenLocations(startPosition, endPosition));
            googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(newPos,20F));
            callback.onFinish();
          });
          valueAnimator.start();
       }

         private static double bearingBetweenLocations(LatLng latLng1,LatLng latLng2) {

           double PI = 3.14159;
           double lat1 = latLng1.latitude * PI / 180;
           double long1 = latLng1.longitude * PI / 180;
           double lat2 = latLng2.latitude * PI / 180;
           double long2 = latLng2.longitude * PI / 180;
           double dLon = (long2 - long1);
           double y = Math.sin(dLon) * Math.cos(lat2);
           double x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon);
           double brng = Math.atan2(y, x);
           brng = Math.toDegrees(brng);
           brng = (brng + 360) % 360;

           return brng;
        }

        public interface LatLngInterpolatorNew {
           LatLng interpolate(float fraction, LatLng a, LatLng b);
           class LinearFixed implements LatLngInterpolatorNew {
            @Override
            public LatLng interpolate(float fraction, LatLng a, LatLng b) {
                double lat = (b.latitude - a.latitude) * fraction + a.latitude;
                double lngDelta = b.longitude - a.longitude;
                // Take the shortest path across the 180th meridian.
                if (Math.abs(lngDelta) > 180) {
                    lngDelta -= Math.signum(lngDelta) * 360;
                }
                double lng = lngDelta * fraction + a.longitude;
                return new LatLng(lat, lng);
            }
        }
    }
}