如何自动添加target=“_空白“;仅限于外部链接

How to automatically add target="_blank" to external links only?

本文关键字:链接 于外部 空白 何自动 添加 target      更新时间:2023-09-26

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

我如何处理html来实现这一点?

我更喜欢服务器端解决方案,但我不知道有任何干净的方法来预处理django中的渲染模板。因此,我认为最直接的方法可能是javascript/jquery解决方案:一个在加载每个页面时运行的脚本,它将target="_blank"属性添加到所有外部链接,而不是内部链接。但我也不知道该怎么做。

我已经使用以下内容一段时间了。记不清我最初在哪里找到的:

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

这添加了一个:externaljQuery选择器,因此您可以执行以下操作:

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

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

尝试类似的东西

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

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

您可以这样做:

$(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,并且它应该在一个新窗口中打开。这是一把正在工作的小提琴。

更新:我确定链接是否留在现场的方法相当粗糙。这个答案中的方法比较彻底。我可能会用那个测试来代替我的简单regex匹配。

我建议您在服务器端这样做。根据链接的位置修改页面的模板。

另一个JavaScript解决方案:

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

由于@Chris Pratt的公认答案不适用于例如tel:links和其他特殊情况,为了不接触特殊链接,我只使用了以下变体:

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

您也可以这样做:

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

代码中的微小更改,不会产生错误,额外的=在!==

$.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');