Comment puis-je tester pour voir si les liens sont externes ou internes? Notez s'il vous plaît:
Je soupçonne que la réponse se trouve quelque part dans location.href, mais la solution m’échappe.
Merci!
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');
}
});
Remarque: ceci est juste un exemple rapide et sale. Cela correspondrait à tous les liens href = "# anchor" as externes également. Il pourrait être amélioré en faisant une vérification supplémentaire de RegExp.
Mise à jour 2016-11-17
Cette question suscitait encore beaucoup de trafic et beaucoup de gens m'ont dit que cette solution acceptée échouerait à plusieurs reprises. Comme je l’ai dit, c’était une réponse très rapide et sale qui montrait le principal moyen de résoudre ce problème. Une solution plus sophistiquée consiste à utiliser les propriétés accessibles sur un élément <a>
(ancre). Comme @Daved déjà souligné dans cette réponse, la clé est de comparer la hostname
avec le window.location.hostname
actuel. Je préférerais comparer les propriétés hostname
, car elles n'incluent jamais la port
qui est incluse dans la propriété Host
si elle diffère de 80.
Alors on y va:
$( 'a' ).each(function() {
if( location.hostname === this.hostname || !this.hostname.length ) {
$(this).addClass('local');
} else {
$(this).addClass('external');
}
});
L'état de l'art:
Array.from( document.querySelectorAll( 'a' ) ).forEach( a => {
a.classList.add( location.hostname === a.hostname || !a.hostname.length ? 'local' : 'external' );
});
Je sais que cet article est vieux mais il reste visible au sommet des résultats, alors je voulais proposer une autre approche. Je vois toutes les vérifications sur les expressions rationnelles sur un élément d'ancrage, mais pourquoi ne pas simplement utiliser window.location.Host
et vérifier la propriété Host
de l'élément?
function link_is_external(link_element) {
return (link_element.Host !== window.location.Host);
}
Avec jQuery:
$('a').each(function() {
if (link_is_external(this)) {
// External
}
});
et avec javascript simple:
var links = document.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
if (link_is_external(links[i])) {
// External
}
}
Et la manière non-jQuery
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"));
}
Tous les hrefs ne commençant pas par http
(http: //, https: //) sont automatiquement traités comme locaux.
var external = RegExp('^((f|ht)tps?:)?//(?!' + location.Host + ')');
Usage:
external.test('some url'); // => true or false
Voici un sélecteur jQuery pour les liens externes uniquement:
$('a[href^="(http:|https:)?//"])')
Un sélecteur jQuery réservé aux liens internes (sans inclure les liens de hachage dans la même page) doit être un peu plus compliqué:
$('a:not([href^="(http:|https:)?//"],[href^="#"],[href^="mailto:"])')
Des filtres supplémentaires peuvent être placés dans la condition :not()
et séparés par des virgules si nécessaire.
http://jsfiddle.net/mblase75/Pavg2/
Alternativement, nous pouvons filtrer les liens internes à l'aide de la propriété Vanilla JavaScript href
, qui est toujours une URL absolue:
$('a').filter( function(i,el) {
return el.href.indexOf(location.protocol+'//'+location.hostname)===0;
})
Vous en avez oublié un, et si vous utilisiez un chemin relatif.
par exemple:/test
hostname = new RegExp(location.Host);
// Act on each link
$('a').each(function(){
// Store current link's url
var url = $(this).attr("href");
// Test if current Host (domain) is in it
if(hostname.test(url)){
// If it's local...
$(this).addClass('local');
}
else if(url.slice(0, 1) == "/"){
$(this).addClass('local');
}
else if(url.slice(0, 1) == "#"){
// It's an anchor link
$(this).addClass('anchor');
}
else {
// a link that does not contain the current Host
$(this).addClass('external');
}
});
Il existe également la question des téléchargements de fichiers .Zip (local et externe) qui pourrait utiliser les classes "téléchargement local" ou "téléchargement externe". Mais nous n'avons pas encore trouvé de solution.
Cela devrait fonctionner pour tout type de lien sur tous les navigateurs sauf IE.
// check if link points outside of app - not working in IE
try {
const href = $linkElement.attr('href'),
link = new URL(href, window.location);
if (window.location.Host === link.Host) {
// same app
} else {
// points outside
}
} catch (e) { // in case IE happens}
Vous pouvez utiliser is-url-external module.
var isExternal = require('is-url-external');
isExternal('http://stackoverflow.com/questions/2910946'); // true | false
/**
* All DOM url
* [links description]
* @type {[type]}
*/
var links = document.querySelectorAll('a');
/**
* Home Page Url
* [HomeUrl description]
* @type {[type]}
*/
var HomeUrl = 'https://stackoverflow.com/'; // Current Page url by-> window.location.href
links.forEach(function(link) {
link.addEventListener('click', function(e) {
e.preventDefault();
// Make lowercase of urls
var url = link.href.toLowerCase();
var isExternalLink = !url.includes(HomeUrl);
// Check if external or internal
if (isExternalLink) {
if (confirm('it\'s an external link. Are you sure to go?')) {
window.location = link.href;
}
} else {
window.location = link.href;
}
})
})
<a href="https://stackoverflow.com/users/3705299/king-rayhan">Internal Link</a>
<a href="https://wordpress.stackexchange.com/">External Link</a>
J'utilise cette fonction pour jQuery:
$.fn.isExternal = function() {
var Host = window.location.Host;
var link = $('<a>', {
href: this.attr('href')
})[0].hostname;
return (link !== Host);
};
L'utilisation est: $('a').isExternal();
Pour les personnes intéressées, j’ai réalisé une version ternaire du bloc if avec un contrôle pour déterminer les classes de l’élément et celles qui sont attachées.
$(document).ready(function () {
$("a").click(function (e) {
var hostname = new RegExp(location.Host);
var url = $(this).attr("href");
hostname.test(url) ?
$(this).addClass('local') :
url.slice(0, 1) == "/" && url.slice(-1) == "/" ?
$(this).addClass('localpage') :
url.slice(0, 1) == "#" ?
$(this).addClass('anchor') :
$(this).addClass('external');
var classes = $(this).attr("class");
console.log("Link classes: " + classes);
$(this).hasClass("external") ? googleAnalytics(url) :
$(this).hasClass("anchor") ? console.log("Handle anchor") : console.log("Handle local");
});
});
Le bit Google Analytics peut être ignoré, mais c’est là que vous voudriez probablement faire quelque chose avec l’URL maintenant que vous savez quel type de lien c’est. Ajoutez simplement du code dans le bloc ternaire . Si vous voulez seulement cocher 1 type de lien, remplacez les ternaires par une instruction if.
Édité pour ajouter un problème que j'ai rencontré. Certains de mes hrefs étaient "/ Courses /" comme ça. J'ai fait un chèque pour une page locale qui vérifie s'il y a une barre oblique au début et à la fin du href. Bien que vérifier le '/' au début soit probablement suffisant.
Oui, je pense que vous pouvez récupérer le nom de domaine actuel avec location.href. Une autre possibilité consiste à créer un élément de lien, à définir le src sur/puis à récupérer l'URL canonique (l'URL de base sera récupérée si vous en utilisez un et pas nécessairement le nom de domaine).
Voir aussi ce post: Obtenir l'URI complet de la propriété href d'un lien