2008-11-25 4 views
7

Pour le suivi de documents non HTML via google analytics, j'ai besoin de l'algorithme mentionné. Il devrait:Javascript: comment déterminer si un lien cible le même domaine que la page sur laquelle il réside?

  • pas coder en dur le domaine
  • ignorer le protocole (par exemple http/https)
  • vous inquiétez pas de la présence/absence de « www » (tous les liens absolus préfixe avec « www » et toutes les pages seront desservies via "www")

Ceci est compliqué par le fait que j'ai besoin d'y accéder via une fonction appelée à partir de IE 'attachEvent' seulement.

MISE À JOUR Désolé, j'ai rédigé cette question vraiment mal. Le vrai problème est de faire fonctionner cela via un événement, puisque IE a son propre monde inventé de gestion des événements. Prenez les éléments suivants:

function add_event(obj) { 
    if (obj.addEventListener) 
     obj.addEventListener('click', track_file, true); 
    else if (obj.attachEvent) 
     obj.attachEvent("on" + 'click', track_file); 
} 

function track_file(obj) { } 

Il semble que le « obj » dans track_file n'est pas le même dans les navigateurs - comment puis-je faire référence à ce qui a été cliqué dans IE?

+0

Est-ce un document que vous ouvrez avec le navigateur? –

+0

Voir http://stackoverflow.com/questions/9404793/check-if-same-origin-policy-applies – Seth

Répondre

5

Je voudrais souligner que, si vous êtes sur so.com, les liens suivants sont des URL dans le même domaine:

(il peut sembler étrange, mais les deux derniers sont valides: si vous re sur http://so.com, le dernier vous amènerait à http://so.com/mail.google.com/index.php?var=value, ce qui est parfaitement valide)

Cela ne répond pas vraiment à la question mais j'espère qu'elle guidera le reste des réponses. S'il y a quelque chose d'assez bizarre, n'hésitez pas à l'ajouter.

+1

aussi href = "javascript: ..." est le même domaine, sauf s'il y a changement de document.location dedans , mais c'est à vous de décider ce que vous allez faire à ce sujet. – vsync

3

Cela ressemble à une réponse de la comédie, mais dans tout le sérieux qu'il serait souhaitable que vous pouvez aussi faire quelque chose comme:

$('a.external') 

Certes, la comparaison des expressions régulières à votre window.location est la réponse programmatique.

+0

Comme il est courant de mettre des liens externes avec 'target =" _ blank "' pour que les visiteurs ne quittent pas la page, vous pouvez également utiliser cet attribut. – Gus

2

La méthode de fixation n'est pas le seul événement manière IE et W3 auditeurs diffèrent. Pour IE, vous devez lire window.event.srcElement; dans W3 c'est event.target où l'événement est le paramètre passé à la fonction de rappel.Si vous n'avez pas besoin de plusieurs gestionnaires d'événements sur les liens, les gestionnaires d'événements DOM 0 old-school sont probablement un moyen plus simple pour vous d'approcher cela, vous permettant d'obtenir l'objet sur n'importe quel navigateur.

function bindtolinks() { 
    for (var i= document.links.length; i-->0;) 
     document.links.onclick= clicklink; 
} 

function clicklink() { 
    if (this.host==window.location.host) { 
     dosomething(); 
     return true; // I'm an internal link. Follow me. 
    } else { 
     dosomethingelse(); 
     return false; // I'm an external link. Don't follow, only do something else. 
    } 
} 
+0

Ce serait génial si je pouvais m'en sortir avec l'approche de la vieille école, mais cela doit être un script très générique qui s'applique à tous les liens sur la page, dont certains pourraient bien avoir des gestionnaires d'événements déjà présents. –

+0

Si vous savez que vous êtes en train de courir après d'autres gestionnaires d'événements, vous pouvez bien sûr sauvegarder (link.orig_onclick = link.onlick) et rappeler le gestionnaire d'événements existant. – bobince

0

Je répondrai à la question de la mise à jour, sur les événements dans IE:

function track_file(evt) 
{ 
    if (evt == undefined) 
    { 
    evt = window.event; // For IE 
    } 
    // Use evt 
} 

est la voie classique pour obtenir objet d'événement cohérent entre les différents navigateurs. Après cela, j'utiliserais les expressions rationnelles pour normaliser l'URL, mais je ne suis pas sûr de ce que vous attendez.

[EDIT] Une partie du code réel pour mettre en pratique ce que je l'ai écrit ci-dessus ... :-)

function CheckTarget(evt) 
{ 
    if (evt == undefined) 
    { 
    // For IE 
    evt = window.event; 
//~  event.returnValue = false; 
    var target = evt.srcElement; 
    var console = { log: alert }; 
    } 
    else 
    { 
    target = evt.target; 
//~  preventDefault(); 
    } 
    alert(target.hostname + " vs. " + window.location.hostname); 
    var re = /^https?:\/\/[\w.-]*?([\w-]+\.[a-z]+)\/.*$/; 
    var strippedURL = window.location.href.match(re); 
    if (strippedURL == null) 
    { 
    // Oops! (?) 
    alert("Where are we?"); 
    return false; 
    } 
    alert(window.location.href + " => " + strippedURL); 
    var strippedTarget = target.href.match(re); 
    if (strippedTarget == null) 
    { 
    // Oops! (?) 
    alert("What is it?"); 
    return false; 
    } 
    alert(target + " => " + strippedTarget); 
    if (strippedURL[1] == strippedTarget[1]) 
    { 
//~  window.location.href = target.href; // Go there 
    return true; // Accept the jump 
    } 
    return false; 
} 

code de test de cela, et non le code de production, évidemment!

Les lignes avec // commentaires indiquent la manière alternative d'empêcher le clic sur le lien de faire le saut. C'est, d'une certaine manière, plus efficace car si j'utilise le fichier console.log de Firebug, curieusement le retour false est inefficace.
J'ai utilisé ici le comportement "suivre le lien ou non", ne connaissant pas le véritable but final.

Comme souligné dans les commentaires, le RE peut être plus simple en utilisant hostname au lieu de href ... Je le laisse car il était déjà codé et pourrait être utile dans d'autres cas.
Certaines précautions spéciales doivent être prises dans les deux cas pour gérer des cas spéciaux, tels que localhost, adresses IP, ports ...
Je me suis débarrassé du nom de domaine, avant de relire la question et de voir qu'il n'y avait pas de problème ... Eh bien, peut-être que cela peut être utile à quelqu'un d'autre.

Note: Je montre une solution similaire dans une question pour décorer les liens: Editing all external links with javascript

+0

En fait, evt.srcElement.hostname (IE) et this.hostname (autres) fonctionne pour moi –

-2
if(someDomElementWhichIsALink.href.indexOf(window.location) != -1) { 
    // this is targeting your domain 
} 
+0

Cela ne détectera pas correctement le même domaine/différent. – Seth

0

Compte tenu d'un événement de clic et l'élément cible d'origine, cela devrait fonctionner pour la question initiale:

if(target.protocol == window.location.protocol && target.host == window.location.host){ 
} 

Les navigateurs convertissent bien le lien des différents modèles mentionnés par @Tom en liens complets, de sorte que les valeurs de protocole et d'hôte doivent simplement correspondre à votre domaine.

Questions connexes