Tester si les liens sont externes avec jQuery / javascript?

Comment tester pour voir si les liens sont externes ou internes? Veuillez noter:

  1. Je ne peux pas coder le domaine local.
  2. Je ne peux pas tester pour"http". Je pourrais tout aussi bien me connecter à mon propre site avec un lien absolu http.
  3. je veux utiliser jQuery / javascript, pas css.

je soupçonne que la réponse se trouve quelque part dans l'emplacement.href, mais la solution m'échappe.

Merci!

57
demandé sur Bhargav Rao 2010-05-26 11:37:25

12 réponses

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: Ceci est juste un exemple rapide et sale. Il correspondrait à tous les liens href="#anchor" comme externe. Il pourrait être amélioré en faisant une vérification supplémentaire de RegExp.


mise à jour 2016-11-17

cette question a encore beaucoup de circulation et j'ai été dit par une tonne de personnes que cette solution acceptée échouera à plusieurs reprises. Comme je l'ai dit, c'était un très rapide et sale réponse à montrer la voie principale comment 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 l'a déjà souligné dans cette réponse, la clé est de comparer le hostname avec le window.location.hostname actuel . Je préférerais comparer les propriétés hostname , car elles n'incluent jamais la propriété port qui est incluse à la propriété host si elle diffère de 80.

So nous y voilà:

$( 'a' ).each(function() {
  if( location.hostname === this.hostname || !this.hostname.length ) {
      $(this).addClass('local');
  } else {
      $(this).addClass('external');
  }
});

Etat de l'art:

Array.from( document.querySelectorAll( 'a' ) ).forEach( a => {
    a.classList.add( location.hostname === a.hostname || !a.hostname.length ? 'local' : 'external' );
});
40
répondu jAndy 2016-11-16 23:44:38

je sais que ce post est vieux mais il montre toujours au sommet des résultats donc je voulais offrir une autre approche. Je vois tous les contrôles regex 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
    }
}
51
répondu Daved 2015-12-29 20:48:11

Et la non-jQuery façon

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 href ne commençant pas par http (http://, https://) sont automatiquement traités comme locaux

37
répondu Sean Kinsey 2012-07-27 03:22:40
var external = RegExp('^((f|ht)tps?:)?//(?!' + location.host + ')');

Utilisation:

external.test('some url'); // => true or false
7
répondu James 2010-05-26 08:28:14

voici un sélecteur jQuery pour Liens externes seulement:

$('a[href^="(http:|https:)?//"])') 

un sélecteur jQuery uniquement pour les liens internes (à l'exclusion des liens de hachage dans la même page) doit être un peu plus compliqué:

$('a:not([href^="(http:|https:)?//"],[href^="#"],[href^="mailto:"])')
Les filtres supplémentaires

peuvent être placés à l'intérieur de la condition :not() et séparés par des virgules supplémentaires si nécessaire.

http://jsfiddle.net/mblase75/Pavg2 /


alternativement, nous pouvons filtrer les liens internes en utilisant la propriété JavaScript vanilla href , qui est toujours une URL absolue:

$('a').filter( function(i,el) {
    return el.href.indexOf(location.protocol+'//'+location.hostname)===0;
})

http://jsfiddle.net/mblase75/7z6EV /

7
répondu Blazemonger 2014-10-21 19:16:58

vous en avez oublié un, et si vous utilisez un chemin relatif.

parexemple: /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 y a aussi la question des téléchargements de fichiers .zip locaux (en externe), qui pourrait utiliser les classes locales "télécharger" ou "externe"télécharger". Mais n'ai pas trouvé de solution pour l'instant.

6
répondu Freelance webdesigner NL 2012-11-06 13:48:08

Vous pouvez utiliser url externe module.

var isExternal = require('is-url-external');
isExternal('http://stackoverflow.com/questions/2910946'); // true | false 
2
répondu mrded 2016-12-19 14:32:55

/**
     * 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>
1
répondu King Rayhan 2018-03-17 10:20:31

Oui, je crois que vous pouvez récupérer le nom de domaine actuel emplacement.href. Une autre possibilité est de créer un élément de lien, de définir le src à / puis de récupérer l'URL canonique (ceci récupérera L'URL de base 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

0
répondu Savageman 2017-05-23 11:54:57

pour les personnes intéressées, j'ai fait une version ternaire du bloc if avec un check pour voir quelles classes l'élément a et quelle classe est attachée.

$(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 aimeriez probablement faire quelque chose avec l'url maintenant que vous savez quel type de lien il s'agit. Il suffit d'ajouter du code dans le bloc ternaire. Si vous voulez seulement vérifier 1 Type de lien, remplacez les ternaires par une instruction if à la place.

édité pour ajouter dans un numéro que je suis tombé sur. Certains de mes href étaient "/Courses/" comme ça. J'ai vérifié s'il y avait un slash au début et à la fin du href. Bien que le simple fait de vérifier Un " / " Au début soit probablement suffisant.

0
répondu George F Delaney 2016-03-23 13:50:57

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

utilisation est: $('a').isExternal();

exemple: https://codepen.io/allurewebsolutions/pen/ygJPgV

0
répondu Allure Web Solutions 2017-10-03 22:22:01

cela devrait fonctionner pour tout type de lien sur chaque navigateur 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}
0
répondu fuuchi 2018-10-02 12:52:33