javascript 打开除域外在新选项卡中打开的所有外部链接
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12071254/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Open all external links open in a new tab apart from a domain
提问by Josh Davies
I'm trying to open all external links on a site in a new window. However on there are 2 versions of the site, e.g. a store and the main site. So on the main site we might have links that go to http://store.example.comfor example.
我正在尝试在新窗口中打开站点上的所有外部链接。但是,该站点有 2 个版本,例如商店和主站点。例如,在主站点上,我们可能有指向http://store.example.com 的链接。
I've got some code here which will allow me to open all the external links in a new window. However I'd like to be able to exclude certain domains. Like the one I've mentioned above.
我这里有一些代码,可以让我在新窗口中打开所有外部链接。但是我希望能够排除某些域。就像我上面提到的那个。
Here is the code:
这是代码:
$(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"
});
}
})
});
I'm new to JS / jQuery so any additional information would be brilliant.
我是 JS / jQuery 的新手,所以任何额外的信息都会很棒。
回答by techfoobar
For triggering the clicks programmatically, you can do something like:
要以编程方式触发点击,您可以执行以下操作:
$(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
}
})
});
回答by Collin Anderson
if you just want all links that don't match your domain name:
如果您只想要所有与您的域名不匹配的链接:
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';
}
}
回答by Mark
Are you able to edit the HTML to get a better hook for maybe a click event? If i need to separate certain links between internal or external i will apply a rel value on the HTML element.
您是否能够编辑 HTML 以获得更好的点击事件挂钩?如果我需要在内部或外部之间分离某些链接,我将在 HTML 元素上应用 rel 值。
<a href="URL" rel="external">Link</a>
Then in your javascript
然后在你的javascript中
$('a[rel="external"]').click( function(event) {
event.stopPropagation();
window.open( $(this).attr('href') );
return false;
});
EDIT: seeing as you already have a ton of links, how about this..
编辑:看到你已经有大量的链接,这个怎么样..
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');
});
}
});
回答by st.
I think I would do it like this:
我想我会这样做:
$(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"
});
}
})
});
It's kinda manual but, if you don't want to deal with splitting strings and arrays, this is the solution. I'm sure this will help.
这有点手动,但是,如果您不想处理拆分字符串和数组,这就是解决方案。我相信这会有所帮助。
Edit: And addition to this, you can use techfoobar's solution for triggering link clicks. That will help you with your websites performance.
编辑:除此之外,您还可以使用 techfoobar 的解决方案来触发链接点击。这将帮助您提高网站性能。
回答by Donagh Hatton
Along the same lines as techfoobar's reply you can build a list of domains that should be left to open in the same window. You can do it in a more robust way though using regular expresions. If you just do a straight indexOf() check you will skip links that have matching subdomains but not matching domains, although you can leave out the '$' if you want to match the name anywhere in the href string.
与 techfoobar 的回复一样,您可以构建一个域列表,这些域应该在同一窗口中打开。尽管使用正则表达式,但您可以以更健壮的方式做到这一点。如果您只是直接进行 indexOf() 检查,您将跳过具有匹配子域但不匹配域的链接,但如果您想匹配 href 字符串中任何位置的名称,则可以省略“$”。
This implementation should do what you want and there are minimal modifications to the code you have needed.
这个实现应该做你想要的,并且对你需要的代码进行最少的修改。
$(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"
});
}
}
})
});
With this example, all links going to google.com and stackoverflow.com will be left to open in the existing page as well.
在此示例中,所有指向 google.com 和 stackoverflow.com 的链接也将在现有页面中打开。
回答by chad steele
If you'd rather use an event handler on body than change the dom, I recommend something like this...
如果你宁愿在 body 上使用事件处理程序而不是更改 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;
});
回答by user3498513
This will do the trick for all external domains using PHP
这将对使用 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
}
})
});
回答by Khom Nazid
Building on Collin's answer in raw JS, which is very nice as it doesn't need Jquery (despite OP's question). I'd amend it to have the ability to exclude domains other than the current hostname though:
基于 Collin 在原始 JS 中的回答,这非常好,因为它不需要 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';
}
}