Подтвердить что ты не робот

Проверьте, являются ли ссылки внешними с jQuery/javascript?

Как проверить, являются ли ссылки внешними или внутренними? Обратите внимание:

  • Я не могу жестко закодировать локальный домен.
  • Я не могу проверить "http". Я мог бы так же легко связываться с моим собственным сайтом с абсолютной ссылкой http.
  • Я хочу использовать jQuery/javascript, а не css.

Я подозреваю, что ответ лежит где-то в location.href, но решение уклоняется от меня.

Спасибо!

4b9b3361

Ответ 1

var comp = new RegExp(location.host);

$('a').each(function(){
   if(comp.test($(this).attr('href'))){
       // a link that contains the current host           
       $(this).addClass('local');
   }
   else{
       // a link that does not contain the current host
       $(this).addClass('external');
   }
});

Примечание. Это просто быстрый и грязный пример. Он будет соответствовать всем ссылкам href= "# anchor" как внешний тоже. Это может быть улучшено путем выполнения дополнительной проверки RegExp.


Обновление 2016-11-17

Этот вопрос по-прежнему получил большой трафик, и многие люди сказали, что это принятое решение несколько раз потерпит неудачу. Как я уже сказал, это был очень быстрый и грязный ответ, чтобы показать основной способ решения этой проблемы. Более сложным решением является использование свойств, доступных для элемента <a> (anchor). Подобно @Daved, уже указанному в этом ответе, ключ должен сравнить hostname с текущим window.location.hostname. Я бы предпочел сравнить свойства hostname, потому что они никогда не включают port, который включен в свойство host, если он отличается от 80.

Итак, идем:

$( 'a' ).each(function() {
  if( location.hostname === this.hostname || !this.hostname.length ) {
      $(this).addClass('local');
  } else {
      $(this).addClass('external');
  }
});

Уровень техники:

Array.from( document.querySelectorAll( 'a' ) ).forEach( a => {
    a.classList.add( location.hostname === a.hostname || !a.hostname.length ? 'local' : 'external' );
});

Ответ 2

Я знаю, что этот пост старый, но он все еще отображается в верхней части результатов, поэтому я хотел предложить другой подход. Я вижу все проверки регулярных выражений на элементе привязки, но почему бы просто не использовать window.location.host и проверить свойство element host?

function link_is_external(link_element) {
    return (link_element.host !== window.location.host);
}

С помощью jQuery:

$('a').each(function() {
    if (link_is_external(this)) {
        // External
    }
});

и с простым javascript:

var links = document.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
    if (link_is_external(links[i])) {
        // External
    }
}

Ответ 3

И путь no-jQuery

var nodes = document.getElementsByTagName("a"), i = nodes.length;
var regExp = new RegExp("//" + location.host + "($|/)");
while(i--){
    var href = nodes[i].href;
    var isLocal = (href.substring(0,4) === "http") ? regExp.test(href) : true;
    alert(href + " is " + (isLocal ? "local" : "not local"));
}

Все hrefs, не начинающиеся с http (http://, https://), автоматически обрабатываются как локальные

Ответ 4

Здесь селектор jQuery для только внешних ссылок:

$('a[href^="(http:|https:)?//"])') 

Селектор jQuery только для внутренних ссылок (не включая хэш-ссылки на одной странице) должен быть немного сложнее:

$('a:not([href^="(http:|https:)?//"],[href^="#"],[href^="mailto:"])')

Дополнительные фильтры могут быть помещены в состояние :not() и разделены дополнительными запятыми по мере необходимости.

http://jsfiddle.net/mblase75/Pavg2/


В качестве альтернативы мы можем фильтровать внутренние ссылки, используя свойство vanilla JavaScript href, которое всегда является абсолютным URL:

$('a').filter( function(i,el) {
    return el.href.indexOf(location.protocol+'//'+location.hostname)===0;
})

http://jsfiddle.net/mblase75/7z6EV/

Ответ 5

var external = RegExp('^((f|ht)tps?:)?//(?!' + location.host + ')');

Использование:

external.test('some url'); // => true or false

Ответ 6

Вы забыли, что, если вы используете относительный путь.

forexample:/test

        hostname = new RegExp(location.host);
            // Act on each link
            $('a').each(function(){

            // Store current link url
            var url = $(this).attr("href");

            // Test if current host (domain) is in it
            if(hostname.test(url)){
               // If it local...
               $(this).addClass('local');
            }
            else if(url.slice(0, 1) == "/"){
                $(this).addClass('local'); 
            }
            else if(url.slice(0, 1) == "#"){
                // It an anchor link
                $(this).addClass('anchor'); 
            }
            else {
               // a link that does not contain the current host
               $(this).addClass('external');                        
            }
        });

Также существует проблема загрузки файлов .zip(local en external), которые могут использовать классы "локальная загрузка" или "внешняя загрузка". Но пока не нашел решения для этого.

Ответ 7

Вы можете использовать is-url-external модуль.

var isExternal = require('is-url-external');
isExternal('http://stackoverflow.com/questions/2910946'); // true | false 

Ответ 8

Да, я считаю, что вы можете получить текущее имя домена с помощью location.href. Другая возможность - создать элемент ссылки, установить src в /, а затем получить канонический URL (это приведет к извлечению базового URL-адреса, если вы используете его, а не обязательно имя домена).

Также см. эту запись: Получить полный URI из свойства href ссылки

Ответ 9

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

$(document).ready(function () {
    $("a").click(function (e) {

        var hostname = new RegExp(location.host);
        var url = $(this).attr("href");

        hostname.test(url) ?
        $(this).addClass('local') :
        url.slice(0, 1) == "/" && url.slice(-1) == "/" ?
        $(this).addClass('localpage') :
        url.slice(0, 1) == "#" ?
        $(this).addClass('anchor') :
        $(this).addClass('external');

        var classes = $(this).attr("class");

        console.log("Link classes: " + classes);

        $(this).hasClass("external") ? googleAnalytics(url) :
        $(this).hasClass("anchor") ? console.log("Handle anchor") : console.log("Handle local");

    });
});

Бит Google Analytics можно игнорировать, но именно здесь вы, вероятно, хотели бы что-то сделать с URL-адресом, чтобы узнать, какой тип ссылки он имеет. Просто добавьте код внутри тройного блока. Если вы хотите проверить только 1 тип ссылки, вместо этого замените тройники инструкцией if.

Отредактировано для добавления проблемы, с которой я столкнулся. Некоторые из моих hrefs были "/Курсы/". Я проверил местную страницу, которая проверяет, есть ли косая черта в начале и конце href. Хотя, вероятно, достаточно проверить наличие "/" в начале.

Ответ 10

Я использую эту функцию для jQuery:

$.fn.isExternal = function() {
  var host = window.location.host;
  var link = $('<a>', {
    href: this.attr('href')
  })[0].hostname;
  return (link !== host);
};

Использование: $('a').isExternal();

Пример: https://codepen.io/allurewebsolutions/pen/ygJPgV