我正在构建一个定制的,行业特定的cms(使用django)。在后端,网站管理员可以指定内部链接,例如“/ page1”或用于整个网站中各种导航元素的外部链接(渲染时全部使用<a>
)。问题是我希望在当前选项卡中打开内部链接,但外部链接应使用target="_blank"
打开新选项卡或窗口。
如何处理html来完成此操作?
我更喜欢服务器端解决方案,但我不知道在django中预处理渲染模板的任何干净方法。因此,我认为最简单的方法可能是javascript / jquery解决方案:在每个页面加载时运行的脚本,它将target =“_ blank”属性添加到所有外部链接但不添加内部链接。但我也不确定如何做到这一点。
答案 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');
})
})();