如何自动将target =“_ blank”添加到外部链接?

时间:2012-08-20 17:05:20

标签: javascript jquery django

我正在构建一个定制的,行业特定的cms(使用django)。在后端,网站管理员可以指定内部链接,例如“/ page1”或用于整个网站中各种导航元素的外部链接(渲染时全部使用<a>)。问题是我希望在当前选项卡中打开内部链接,但外部链接应使用target="_blank"打开新选项卡或窗口。

如何处理html来完成此操作?

我更喜欢服务器端解决方案,但我不知道在django中预处理渲染模板的任何干净方法。因此,我认为最简单的方法可能是javascript / jquery解决方案:在每个页面加载时运行的脚本,它将target =“_ blank”属性添加到所有外部链接但不添加内部链接。但我也不确定如何做到这一点。

8 个答案:

答案 0 :(得分:35)

我一直在使用以下内容。不记得我最初在哪里找到它:

$.expr[':'].external = function(obj){
    return !obj.href.match(/^mailto\:/)
           && (obj.hostname != location.hostname)
           && !obj.href.match(/^javascript\:/)
           && !obj.href.match(/^$/)
};

这会添加一个:external jQuery选择器,所以你可以这样做:

$('a:external').attr('target', '_blank');

使用自定义选择器的好处是,如果您需要修改构成“外部”链接的内容,您可以在一个地方更改它,而不用担心代码的其余部分。例如,在我的组织中,我们有某些不是“外部”的子域,但我们仍然希望在新窗口中打开。

答案 1 :(得分:5)

尝试类似

的内容
for (var links = document.links, i = 0, a; a = links[i]; i++) {
        if (a.host !== location.host) {
                a.target = '_blank';
        }
}

不要忘记在文档树中存在所有链接时运行脚本 - 在window.onload事件中。

答案 2 :(得分:3)

你可以这样做:

$(document.body).on('mouseover', 'a[target!=_blank]:not(.local)', function (evt) {
    var a = $(this);
    var href = a.attr('href');
    var domain = href.match(/^https?:\/\/([^:\/]+)/);
    if (domain && domain[1] && domain[1] !== "yourdomain.com") {
        a.attr('target', '_blank');
    } else {
        a.addClass('local');
    }
});

这会在您点击它时处理每个链接,并且不应多次处理每个链接。如果它必须是外部的,target将设置为_blank,它应该在新窗口中打开。 Here's a working jsfiddle

更新:我确定链接是否停留在现场的方法非常粗糙。 this answer中的方法更为彻底。我可能会用这个测试替换我的简单正则表达式匹配。

答案 3 :(得分:2)

我建议你做那个服务器端。 根据链接的位置修改页面模板。

答案 4 :(得分:1)

由于@Chris Pratt的广泛接受的答案不适用于例如tel:链接和其他特殊情况为了避免触及特殊链接,我只使用以下变体:

(function($) {

    $.expr[':'].external = function(obj){
        return (obj.hostname != location.hostname) && obj.href.startsWith("http");
    };

    $('a:external').attr('target', '_blank');

}) (jQuery);

答案 5 :(得分:0)

你也可以这样做:

$("a[href^='http://']").attr("target","_blank");

$('a').each(function() {
   var a = new RegExp('/' + window.location.host + '/');
   if(!a.test(this.href)) {
       $(this).click(function(event) {
           event.preventDefault();
           event.stopPropagation();
           window.open(this.href, '_blank');
       });
   }
});

答案 6 :(得分:0)

代码略有变化,不会产生错误,附加= in!==

$.expr[':'].external = function(obj){
    return !obj.href.match(/^mailto\:/) && (obj.hostname !== location.hostname) && !obj.href.match(/^javascript\:/) && !obj.href.match(/^$/);
};
$('a:external').attr('target', '_blank');

答案 7 :(得分:0)

另一种JavaScript解决方案:

(() => {
  (document.querySelectorAll('a')).forEach(link => {
    link.hostname !== location.hostname && link.setAttribute('target', '_blank');
  })
})();