Javascript: как определить, имеет ли ссылка тот же домен, что и страница, на которой она находится? - PullRequest
7 голосов
/ 25 ноября 2008

Для отслеживания не-HTML документов с помощью Google Analytics мне нужен упомянутый алгоритм. Стоит:

  • без жесткого кода домена
  • игнорировать протокол (т.е. http / https)
  • не беспокойтесь о наличии / отсутствии «www» (любые абсолютные ссылки БУДУТ префиксом «www» и все страницы будут обслуживаться через «www»)

Это осложняется тем фактом, что мне нужно получить к нему доступ через функцию, вызываемую только из IE «attachEvent».

ОБНОВЛЕНИЕ Извините, я сформулировал этот вопрос действительно плохо. Реальная проблема заключается в том, чтобы заставить это работать через событие, так как IE имеет свой собственный мир обработки событий. Возьмите следующее:

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

Кажется, что "obj" в track_file не одинаков во всех браузерах - как я могу сослаться на то, что щелкнуло в IE?

Ответы [ 7 ]

5 голосов
/ 25 ноября 2008

Хочу отметить, что если вы находитесь на so.com, следующие ссылки являются URL-адресами в пределах одного домена:

(это может показаться странным, но последние два действительны: если вы находитесь на http://so.com,, последний из них приведет вас к http://so.com/mail.google.com/index.php?var=value,, что совершенно правильно)

Это на самом деле не отвечает на вопрос, но я надеюсь, что он будет направлять остальные ответы. Если есть что-то еще достаточно странное, не стесняйтесь добавлять это.

3 голосов
/ 25 ноября 2008

Это звучит как комедийный ответ, но со всей серьезностью было бы целесообразно сделать что-то вроде:

$('a.external')

Конечно, сравнение регулярных выражений с вашим window.location является программным ответом.

2 голосов
/ 25 ноября 2008

Метод прикрепления - не единственный способ различения прослушивателей событий IE и W3. Для IE вы должны прочитать window.event.srcElement; в W3 это event.target, где event - это параметр, передаваемый в функцию обратного вызова.

Если вам не нужны несколько обработчиков событий для ссылок, обработчики событий старой школы DOM 0, вероятно, являются более простым способом приблизиться к этому, позволяя просто использовать «this» для получения объекта в любом браузере. 1003 *

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 голосов
/ 19 октября 2010

С учетом события щелчка и исходного целевого элемента это должно работать для исходного вопроса:

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

Браузеры прекрасно преобразуют ссылки из различных шаблонов, упомянутых @Tom, в полные ссылки, поэтому значения протокола и хоста просто должны соответствовать вашему домену.

0 голосов
/ 25 ноября 2008
if( someDomElementWhichIsALink.href.indexOf(window.location) != -1 ) {
  // this is targeting your domain
}
0 голосов
/ 25 ноября 2008

Я отвечу на вопрос в обновлении, о событиях в IE:

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

- это классический способ получения согласованного объекта события в браузерах.

После этого я бы использовал регулярные выражения для нормализации URL, но я не уверен, что вы ищете.

[EDIT] Какой-то реальный код, чтобы применить на практике то, что я написал выше ...: -)

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

Это тестовый код, а не рабочий код, очевидно!

Строки с комментариями // ~ показывают альтернативный способ предотвратить переход по ссылке. Это, так или иначе, более эффективно, потому что, если я использую консоль Firebug console.log, любопытно, что возвращаемое значение false неэффективно.
Я использовал здесь поведение «переходить по ссылке или нет», не зная реальной конечной цели.

Как указано в комментариях, RE может быть проще, если использовать имя хоста вместо href ... Я оставляю его как есть, поскольку оно уже закодировано и может быть полезно в других случаях.
В обоих случаях необходимо принять некоторые особые меры предосторожности для обработки особых случаев, таких как localhost, IP-адреса, порты ...
Я избавился от доменного имени, прежде чем перечитать вопрос и убедиться, что это не проблема ... Ну, может быть, это может быть полезно кому-то еще.

Примечание: я показал аналогичное решение в вопросе для оформления ссылок: Редактирование всех внешних ссылок с помощью javascript

0 голосов
/ 25 ноября 2008

Может быть, это поможет: http://www.quirksmode.org/js/events_properties.html#target

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...