2009-08-04 17 views
10

Desidero scrivere uno script che può determinare se un collegamento è interno o esterno. Questo è semplice dal mio punto di vista, tutti i collegamenti interni sono relativi, quindi iniziano con /. Tutti i collegamenti esterni iniziano con un http: // - tutto bene finora. Tuttavia non riesco a capire come fare un ': contains()' su qualcosa di diverso dal testo - come può una ricerca di una stringa all'interno di un attributo?Utilizzo di jQuery per verificare se un collegamento è interno o esterno

Una volta che posso fare questo sono felice di aggiungere bersaglio me _blank, a meno che non si conosce un modo migliore per farlo

risposta

22

Si potrebbe utilizzare la sintassi attribute^=value per trovare HREF che iniziano con http o /:

$("a[href^='http']") // external 

$("a[href^='/']") // internal 

Ecco una soluzione migliore: è possibile aggiungere $('a:external') e $('a:internal') selettori per jQuery con il codice del plugin di seguito. Qualsiasi URL che inizia http://, https:// o whatever:// è considerato esterno.

$.expr[':'].external = function (a) { 
     var PATTERN_FOR_EXTERNAL_URLS = /^(\w+:)?\/\//; 
     var href = $(a).attr('href'); 
     return href !== undefined && href.search(PATTERN_FOR_EXTERNAL_URLS) !== -1; 
    }; 

    $.expr[':'].internal = function (a) { 
     return $(a).attr('href') !== undefined && !$.expr[':'].external(a); 
    }; 
+0

Grazie, che sembra funzionare come descritto. Saluti – chrism

+8

Ho ragione nel dire che un url interno non inizierà sempre con una barra in avanti. potrebbe essere meglio usare $ ('a [href! = http:] a [href! = https:]') per interno. – kim3er

+0

Per quello che stavo facendo, i selettori degli attributi erano l'opzione migliore. Tuttavia, c'è un piccolo problema con loro. Dovrebbero essere $ ('a [href^= "http"]') e $ ('a [href^= "/"]') – Tony

8

sto usando WordPress per il mio CMS, e quindi la maggior parte (se non tutti) dei miei collegamenti interni iniziano con "http". Ho trovato una soluzione piuttosto interessante qui: http://www.focal55.com/blog/jquery-tutorial-add-class-all-outbound-links-your-site

Nel caso in cui questo sito è giù, si riduce sostanzialmente verso il basso per questo selettore (ho modificato un po '):

$('a[href^="//"],a[href^="http"]') 
    .not('[href*="' + window.location.hostname + '"]') 
; 

Si noti che questo selettore si not be the fastest in base alle i documenti jQuery.

+0

Questo ha finito per funzionare perfettamente per me – Miva

+0

Felice di sentirlo. Tieni presente che potrebbero esserci alcuni casi limite in cui mancheranno link esterni. Qualcosa di simile a external.com/?ref=internal.com probabilmente lo farà inciampare. Non ho ancora trovato nulla di simile nel mio utilizzo, ma potrebbe essere utile saperlo. –

1

Io uso questo per trovare tutti gli URL che punta al domain other than current domain o uno con (HTML5 deprecato) attribute target="_blank"

var contrastExternalLinks = function() { 
    //create a custom external selector for finding external links 
    $.expr[':'].external = function(obj) { 
     return (
      $(obj).attr('target') && $(obj).attr('target') =='_blank') 
       || 
        (!obj.href.match(/^mailto\:/) && !obj.href.match(/^tel\:/) && (obj.hostname != location.hostname) 
         ); 
    }; 
    // Usage: 
    $(document).ready(function() { 
     $('a:external').addClass('external');///css('background-color', 'green'); 
    }) 



}(); 
3

selezionare solo ancore che puntano al tuo dominio quando href è l'URL completo .

jQuery("a:not([href^='http://']), " + 
     "a[href^='http://localhost.com'], " + 
     "a:not([href^='http://localhost.com/wp-admin'])").addClass("internal"); 
3

preferisco questo selettore me stesso, protegge contro i falsi positivi per i collegamenti assoluti che puntano al tuo sito (come quelli spesso generato da un sistema CMS).

var currentDomain = document.location.protocol + '//' + document.location.hostname; 
var outboundLinks = 'a[href^="http"]:not([href*="' + currentDomain + '"])'; 

Ecco il caso d'uso in cui questo ha funzionato per me, per il contesto:

var currentDomain = document.location.protocol + '//' + document.location.hostname; 
$('a[href^="http"]:not([href*="' + currentDomain + '"])').on('click', function (e) { 
    e.preventDefault(); 

    // track GA event for outbound links 
    if (typeof _gaq == "undefined") 
     return; 

    _gaq.push(["_trackEvent", "outbound", this.href, document.location.pathname + document.location.search]); 
}); 
0

penso che l'approccio semplice e meno mal di testa per questo non è quello di utilizzare puro JavaScript o jQuery, ma combinano con html e poi controlla se il link cliccato contenente l'url del tuo sito di base. Funzionerà per qualsiasi tipo di url di base (es .: example.com, example.com/site). Se hai bisogno di un valore dinamico, devi solo impostare il valore usando il tuo linguaggio di programmazione lato server preferito, come PHP, asp, java ecc.

Ecco un esempio:

HTML

<!--Create a hidden input containing your base site's url.--> 
<input type="hidden" id="sitedomain" value="example.com/site"/> 

jQuery

$(".elem").on("click", function(e){ 
    if($(this).closest("a").length) { 
    var url = $(this).attr("href"); 
    var sitedomain = $("#sitedomain").val(); 

    if(url.indexOf(sitedomain) > -1) { 
    alert("Internal"); 
    } else { 
    alert("External"); 
    } 
} 
}); 
0

provare

var fullBaseUrl = 'https://internal-link.com/blog'; 

var test_link1 = 'https://internal-link.com/blog/page1'; 
var test_link2 = 'https://internal-link.com/shop'; 
var test_link3 = 'https://google.com'; 

test_link1.split(fullBaseUrl)[0] == ''; // True 
test_link2.split(fullBaseUrl)[0] == ''; // False 
test_link3.split(fullBaseUrl)[0] == ''; // False 
+1

Sebbene questo codice possa rispondere alla domanda, fornendo un contesto aggiuntivo relativo a ** come ** e ** perché ** risolve il problema, migliorerebbe il valore a lungo termine della risposta. – Alexander

0
$(document).ready(function() { 
$('a[href^="http"]').not('a[href^="http://' + $(location).attr('hostname') + 
'"]').attr('target', '_blank'); 
}); 

sostituire "http" con "https", se avete bisogno di

Problemi correlati