This morning my friend Giuseppina, an Italian web developer, was visiting my main website when she noticed some mysterious popups in my resumé page. She informed me about this strange behavior on Facebook. My first thought was that my site was broken or perhaps hacked but later I realized that the multiple popups, all pointing to the current page, were due to an incorrect use of the indexOf()
method with jQuery.
The code was the following:
if ($('a', '#content').length) {
$('a', '#content').each(function() {
var $a = $(this),
href = $a.attr('href'),
$img = $('img', $a);
if (!$a.hasClass('more-link')) {
if (!$img.length && href.indexOf(BASEURL) == -1 && href.indexOf('twitter') == -1 && href.indexOf('facebook') == -1 && href.indexOf('mailto') == -1) {
$a.addClass('external');
$a.click(function() {
$a.attr('target', '_blank');
window.open($a.attr('href'));
return false;
});
}
}
});
}
I was trying to add a special class to all my external links by also allowing a visitor to open them in a new window. The problem is that the above if
clause with indexOf()
also matches hashes and anchors which are present in my resumé page.
My main URL is stored in the BASEURL
variable which is http://gabrieleromanato.com/
. Of course I had to take care of mailto
links plus the URIs generated by the social media buttons.
The problem with my method is that is not exclusive but inclusive. A URL like http://gabrieleromanato.com/page/#section
will be also considered as an external link.
indexOf()
scans the entire string searching for a substring that matches the argument passed to it. Here we need regular expressions:
var urlRegExp = /^#|(https?:\/\/(www)?(gabrieleromanato|twitter|facebook))|(mailto:)/;
if(!urlRegExp.test(href)) {
$a.addClass('external');
}
Simple enough. And thanks Giuseppina!