2008-11-25 7 views
7

Para el seguimiento de documentos no HTML a través de Google Analytics, necesito el algoritmo mencionado. Se debe:Javascript: ¿cómo puedo determinar si un enlace se dirige al mismo dominio que la página en la que reside?

  • no es difícil de código del dominio
  • ignoran el protocolo (es decir, http/https)
  • no preocuparse de la presencia/ausencia de "www" (ningún enlace absolutos prefijará con "www" y todas las páginas SERÁN atendidas a través de "www")

Esto se complica por el hecho de que necesito acceder a él a través de una función llamada desde IE-only 'attachEvent'.

ACTUALIZACIÓN Lo sentimos, he redactado esta pregunta muy mal. El verdadero problema es hacer que esto funcione a través de un evento, ya que IE tiene su propio mundo inventado de manejo de eventos. Tomemos el siguiente:

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

Parece como si el "obj" en track_file no es la misma en todos los navegadores - ¿Cómo puedo referir a lo que se ha hecho clic en el IE?

+0

¿Es un documento que abre con el navegador? –

+0

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

Respuesta

5

me gustaría señalar que, si estás en so.com, los siguientes enlaces son direcciones URL dentro del mismo dominio:

(puede parecer extraño, pero los dos últimos son válidos: si' re en http://so.com, el último lo llevaría a http://so.com/mail.google.com/index.php?var=value, que es perfectamente válido)

Esto realmente no responde la pregunta, pero espero que sirva de guía para el resto de las respuestas. Si hay algo más extraño, no dude en agregarlo.

+1

también href = "javascript: ..." es el mismo dominio, excepto si tiene un cambio de documento.location dentro de él , pero depende de ti, entonces, ¿qué vas a hacer al respecto? – vsync

3

Esto suena como una respuesta comedia, pero con toda seriedad que sería conveniente que también se podría hacer algo como:

$('a.external') 

Ciertamente, la comparación de expresiones regulares a su window.location es la respuesta programática.

+0

Dado que es común poner enlaces externos con 'target = '_ blank' 'para que los visitantes no abandonen la página, también puede usar ese atributo. – Gus

2

El método de fijación no es la única manera de IE y W3 detectores de eventos difieren. Para IE, debe leer window.event.srcElement; en W3 es event.target donde evento es el parámetro pasado a la función de devolución de llamada.

Si no necesita múltiples controladores de eventos en los enlaces, los manejadores de eventos DOM 0 de la vieja escuela son probablemente una forma más fácil de acercarse a esto, permitiéndonos simplemente 'esto' obtener el objeto en cualquier navegador.

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

Sería fantástico si pudiera salirse con la suya con el enfoque de la vieja escuela, pero tiene que ser una secuencia de comandos muy genérica que solo se aplique a todos los enlaces de la página, algunos de los cuales pueden tener ya manejadores de eventos. –

+0

Si sabe que se está ejecutando después de otros controladores de eventos, puede, por supuesto, guardar (link.orig_onclick = link.onlick) y volver a llamar al controlador de eventos existente. – bobince

0

voy a responder a la pregunta en la actualización, sobre los acontecimientos en IE:

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

es la forma clásica de obtener objeto de evento consistente a través de los navegadores.

Después de eso, usaría expresiones regulares para normalizar la URL, pero no estoy seguro de lo que cuida.

[EDIT] Algunos código real para poner en práctica lo que he escrito anteriormente ... :-)

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

de ese código de prueba, no el código de producción, obviamente!

Las líneas con // ~ comentarios muestran la forma alternativa de evitar que el clic en el enlace haga el salto. Es, de alguna manera, más eficiente porque si uso la consola console.log de Firebug, curiosamente la devolución falsa es ineficaz.
Utilicé aquí el comportamiento "Seguir enlace o no", sin conocer el verdadero propósito final.

Como se señala en los comentarios, la RE puede ser más simple usando nombre de host en lugar de href ... Lo dejo porque ya estaba codificado y podría ser útil en otros casos.
Deben tomarse algunas precauciones especiales en ambos casos para manejar casos especiales, como localhost, direcciones IP, puertos ...
Me deshice del nombre de dominio, antes de volver a leer la pregunta y ver que no era un problema ... Bueno, quizás pueda ser útil para otra persona.

Nota: Me muestra una solución similar en una pregunta para decorar enlaces: Editing all external links with javascript

+0

En realidad, evt.srcElement.hostname (IE) y this.hostname (others) funciona para mí –

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

Esto no detectará correctamente el mismo/diferente dominio. – Seth

0

Dado un evento de clic y el elemento objetivo original, esto debería funcionar para la pregunta original:

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

Los navegadores convierten agradablemente el enlace de los diversos patrones mencionados por @Tom en enlaces completos, por lo que el protocolo y los valores de host simplemente tienen que coincidir con su dominio.

Cuestiones relacionadas