Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何自动添加目标="_“空白”;只连接到外部链接?_Javascript_Jquery_Django - Fatal编程技术网

Javascript 如何自动添加目标="_“空白”;只连接到外部链接?

Javascript 如何自动添加目标="_“空白”;只连接到外部链接?,javascript,jquery,django,Javascript,Jquery,Django,我正在构建一个定制的、特定于行业的cms(使用django)。在后端,网站管理员可以指定内部链接,例如“/page1”或外部链接,用于整个网站的各种导航元素(呈现时都使用)。问题是我希望在当前选项卡中打开内部链接,但外部链接应使用target=“\u blank”打开新选项卡或窗口 如何处理html以实现这一点 我更喜欢服务器端解决方案,但不知道有什么干净的方法可以在django中预处理呈现的模板。因此,我假设实现这一点最直接的方法可能是javascript/jquery解决方案:一个在每个页面

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

如何处理html以实现这一点


我更喜欢服务器端解决方案,但不知道有什么干净的方法可以在django中预处理呈现的模板。因此,我假设实现这一点最直接的方法可能是javascript/jquery解决方案:一个在每个页面加载时运行的脚本,它将target=“\u blank”属性添加到所有外部链接,而不是内部链接。但我也不知道该怎么做

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

尝试以下操作

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

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

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

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

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

您可以执行以下操作:

$(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');
    }
});
这将在您单击每个链接时对其进行处理,并且不应多次处理每个链接。如果需要是外部的,
目标
将设置为
\u blank
,并应在新窗口中打开


更新:我确定链接是否留在现场的方法相当粗糙。中的方法更彻底。我可能会用该测试替换我的简单正则表达式匹配。

您也可以这样做:

$([a[href^='http://'])attr(“target”,“_blank”)


代码中的微小更改,不会出现错误,额外=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');

另一个JavaScript解决方案:

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

由于@Chris Pratt的公认答案不适用于例如电话:链接和其他特殊情况,我仅使用以下变体,以避免接触特殊链接:

(function($) {

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

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

}) (jQuery);

虽然我很欣赏你的观点,但我想我会等着看是否有人真的可以建议如何通过django在服务器端实现这一点。我只是编辑了它,以使其成为以前的版本(而且很明显)implicit question explicit.id使用中间件在服务器端执行此操作,中间件解析响应并在所需位置替换代码。您可以使用beautifulsoup进行解析。这是一个有趣的实时解决方案。还没有完全起作用。我现在必须帮助面试,但过一会儿会回来编辑。我想我更喜欢克里斯的答案,但我已经对你的答案投了更高的票。所以请随意清理它;我只是想提醒你,我可能要去另一个方向,所以不要着急。他的回答很好。我认为我的优势所在的唯一方法是,您可以使用javascript动态添加链接,它们将自动工作,而无需再次运行此代码。这就是
。on
函数:)的美妙之处,这很酷。我以前从未以这种方式扩展过jquery,但我喜欢简单的用法以及您提到的优点。这种确定主机名是在现场还是在非现场的方法非常好。比我的要彻底得多。这太棒了。谢谢。我已经在生产中使用这个产品很多年了,很明显至少有17个人认为它有效。这对你怎么不起作用?您是否遇到任何错误?我认为使用jQuery的.ready()比使用window.onload更合适,因为.ready()会在DOM完全加载后立即启动,而window.onload在加载所有资源(图像等)后才会启动这意味着用户有可能在添加目标之前单击。@strille问题没有标记为jQuery,因此我不想使用它,而且我不想让OP与
DOMContentLoaded
+回退解决方案混淆,因为它不是跨浏览器的。但是你是对的。很抱歉忘记了最初的jquery标记。如果您愿意,可以随时使用jquery修改答案。不管怎样,我都投了赞成票。
(function($) {

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

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

}) (jQuery);