Javascript: как определить, нацелена ли ссылка на тот же домен, что и страница, на которой она находится?

Для отслеживания документов, отличных от 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?

Это документ, который вы открываете в браузере?

Georg Schölly 25.11.2008 14:36

См. stackoverflow.com/questions/9404793/…

Seth 08.06.2016 18:14
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
8
2
6 686
7

Ответы 7

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

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

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

также href = "javascript: ..." - тот же домен, за исключением случаев, когда в нем есть изменение document.location, но что делать с этим - решать вам.

vsync 15.10.2009 12:46

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

$('a.external')

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

Поскольку внешние ссылки обычно размещаются с помощью target = "_blank", чтобы посетители не покидали страницу, вы также можете использовать этот атрибут.

Gus 24.09.2017 15:54

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

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

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

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

Bobby Jack 25.11.2008 15:52

Если вы знаете, что работаете после других обработчиков событий, вы, конечно, можете сохранить (link.orig_onclick = link.onlick) и повторно вызвать существующий обработчик событий.

bobince 25.11.2008 22:38

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

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

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

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

[РЕДАКТИРОВАТЬ] Какой-то реальный код, чтобы применить на практике то, что я написал выше ... :-)

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.info, любопытно, что return false неэффективен. Я использовал здесь поведение «переходить по ссылке или нет», не зная истинной конечной цели.

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

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

На самом деле у меня работают evt.srcElement.hostname (IE) и this.hostname (другие)

Bobby Jack 25.11.2008 15:53
if ( someDomElementWhichIsALink.href.indexOf(window.location) != -1 ) {
  // this is targeting your domain
}

Это не приведет к правильному обнаружению одного и того же / другого домена.

Seth 08.06.2016 18:11

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

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

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

Другие вопросы по теме