Test if links are external with jQuery / javascript?
How do I test to see if links are external or internal? Please note:
- I cannot hard code the local domain.
- I cannot test for "http". I could just as easily be linking to my own site with an http absolute link.
- I want to use jQuery / javascript, not css.
I suspect the answer lies somewhere in location.href, but the solution evades me.
Thanks!
Solution 1:
I know this post is old but it still shows at the top of results so I wanted to offer another approach. I see all the regex checks on an anchor element, but why not just use window.location.host
and check against the element's host
property?
function link_is_external(link_element) {
return (link_element.host !== window.location.host);
}
With jQuery:
$('a').each(function() {
if (link_is_external(this)) {
// External
}
});
and with plain javascript:
var links = document.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
if (link_is_external(links[i])) {
// External
}
}
Solution 2:
var comp = new RegExp(location.host);
$('a').each(function(){
if(comp.test($(this).attr('href'))){
// a link that contains the current host
$(this).addClass('local');
}
else{
// a link that does not contain the current host
$(this).addClass('external');
}
});
Note: this is just a quick & dirty example. It would match all href="#anchor" links as external too. It might be improved by doing some extra RegExp checking.
Update 2016-11-17
This question still got a lot of traffic and I was told by a ton of people that this accepted solution will fail on several occasions. As I stated, this was a very quick and dirty answer to show the principal way how to solve this problem. A more sophisticated solution is to use the properties which are accessible on a <a>
(anchor) element. Like @Daved already pointed out in this answer, the key is to compare the hostname
with the current window.location.hostname
. I would prefer to compare the hostname
properties, because they never include the port
which is included to the host
property if it differs from 80.
So here we go:
$( 'a' ).each(function() {
if( location.hostname === this.hostname || !this.hostname.length ) {
$(this).addClass('local');
} else {
$(this).addClass('external');
}
});
State of the art:
Array.from( document.querySelectorAll( 'a' ) ).forEach( a => {
a.classList.add( location.hostname === a.hostname || !a.hostname.length ? 'local' : 'external' );
});
Solution 3:
And the no-jQuery way
var nodes = document.getElementsByTagName("a"), i = nodes.length;
var regExp = new RegExp("//" + location.host + "($|/)");
while(i--){
var href = nodes[i].href;
var isLocal = (href.substring(0,4) === "http") ? regExp.test(href) : true;
alert(href + " is " + (isLocal ? "local" : "not local"));
}
All hrefs not beginning with http
(http://, https://) are automatically treated as local