jQuery: selezionare i link esterni nel modo corretto

jQuery: selezionare i link esterni nel modo corretto

Un paio di settimane fa Giuseppina mi ha inviato un messaggio su Facebook informandomi che nella sezione curriculum vitae del mio sito si aprivano numerose popup quando si cliccava sui link del sommario. Il problema era dovuto al mio tentativo di selezionare i link esterni con jQuery nel modo sbagliato.

Il codice incriminato era il seguente:


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;
				});
			}
		}
	});
}

La variabile BASEURL contiene l'URL principale del sito. Dal codice appare chiaro come io stessi cercando di aggiungere una classe CSS ai link esterni facendo aprire questi ultimi in una nuova finestra.

Volevo inoltre escludere dalla selezione i link dei pulsanti dei social network e quelli contenenti indirizzi e-mail. Il problema è che l'uso di indexOf() in un costrutto booleano è errato: nel caso specifico non si teneva conto delle ancore (hash) presenti nei link, ed era proprio questo che causava il problema nella sezione del sito che usava tali ancore.

La soluzione è quella di usare un'espressione regolare:


var urlRegExp = /^#|(https?:\/\/(www)?(gabrieleromanato|twitter|facebook))|(mailto:)/;
if(!urlRegExp.test(href)) {
	$a.addClass('external');
}

L'espressione regolare usata sopra seleziona tutti quei link il cui URL inizia con un #, con l'URL del mio sito o con l'URL principale di Twitter o Facebook. Inoltre seleziona anche i link mailto:.

Con un semplice costrutto NOT abbinato al metodo test() verifico che l'URL non corrisponda all'espressione regolare. Solo in quel caso posso aggiungergli una classe CSS speciale.

Un ringraziamento speciale va a Giuseppina per la tempestiva segnalazione.

Torna su