Проверьте, являются ли ссылки внешними с jQuery / javascript?
Как проверить, являются ли ссылки внешними или внутренними? Обратите внимание:
- Я не могу жестко кодировать локальный домен.
- Я не могу проверить "http". Я мог бы так же легко ссылаться на свой собственный сайт с абсолютной ссылкой http.
- Я хочу использовать jQuery / javascript, а не css.
Я подозреваю, что ответ лежит где-то в другом месте.близко, но решение ускользает от меня.
спасибо!
12 ответов
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>
(якорным) элементом. Как @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' );
});
Я знаю, что этот пост старый, но он по-прежнему отображается в верхней части результатов, поэтому я хотел предложить другой подход. Я вижу все проверки регулярных выражений на элементе привязки, но почему бы просто не использовать window.location.host
и проверьте против элемента 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
}
}
и путь 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://) автоматически рассматриваются как локальные
var external = RegExp('^((f|ht)tps?:)?//(?!' + location.host + ')');
использование:
external.test('some url'); // => true or false
вот селектор jQuery только для внешних ссылок:
$('a[href^="(http:|https:)?//"])')
селектор jQuery только для внутренних ссылок (не включая хэш-ссылки на одной странице) должен быть немного сложнее:
$('a:not([href^="(http:|https:)?//"],[href^="#"],[href^="mailto:"])')
дополнительные фильтры можно поместить внутри :not()
условие и разделены дополнительными запятыми по мере необходимости.
http://jsfiddle.net/mblase75/Pavg2/
альтернативно, мы можем фильтровать внутренние ссылки используя ванильный JavaScript href
свойство, которое всегда является абсолютным URL:
$('a').filter( function(i,el) {
return el.href.indexOf(location.protocol+'//'+location.hostname)===0;
})
вы забыли одно, что если вы используете относительный путь.
forexample: / test
hostname = new RegExp(location.host);
// Act on each link
$('a').each(function(){
// Store current link's url
var url = $(this).attr("href");
// Test if current host (domain) is in it
if(hostname.test(url)){
// If it's local...
$(this).addClass('local');
}
else if(url.slice(0, 1) == "/"){
$(this).addClass('local');
}
else if(url.slice(0, 1) == "#"){
// It's an anchor link
$(this).addClass('anchor');
}
else {
// a link that does not contain the current host
$(this).addClass('external');
}
});
существует также проблема загрузки файлов .zip (local en external), который может использовать классы "локальная загрузка" или "внешняя загрузка". Но пока не нашел решения.
можно использовать is-url-external модуль.
var isExternal = require('is-url-external');
isExternal('http://stackoverflow.com/questions/2910946'); // true | false
/**
* All DOM url
* [links description]
* @type {[type]}
*/
var links = document.querySelectorAll('a');
/**
* Home Page Url
* [HomeUrl description]
* @type {[type]}
*/
var HomeUrl = 'https://stackoverflow.com/'; // Current Page url by-> window.location.href
links.forEach(function(link) {
link.addEventListener('click', function(e) {
e.preventDefault();
// Make lowercase of urls
var url = link.href.toLowerCase();
var isExternalLink = !url.includes(HomeUrl);
// Check if external or internal
if (isExternalLink) {
if (confirm('it\'s an external link. Are you sure to go?')) {
window.location = link.href;
}
} else {
window.location = link.href;
}
})
})
<a href="https://stackoverflow.com/users/3705299/king-rayhan">Internal Link</a>
<a href="https://wordpress.stackexchange.com/">External Link</a>
Да, я считаю, что вы можете получить текущее доменное имя с местоположением.хреф. Другая возможность-создать элемент link, установить src В / , а затем получить канонический URL (это будет получать базовый URL, если вы используете один, и не обязательно доменное имя).
Также см. Этот пост: получить полный URI из свойства href ссылки
для тех, кто заинтересован, я сделал троичную версию блока 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 были " / Courses/", как таковые. Я сделал проверку для localpage, которая проверяет, есть ли косая черта в начале и конце href. Хотя, вероятно, достаточно просто проверить " / " в начале.
Я использую эту функцию для jQuery:
$.fn.isExternal = function() {
var host = window.location.host;
var link = $('<a>', {
href: this.attr('href')
})[0].hostname;
return (link !== host);
};
использование: $('a').isExternal();
Это должно работать для любой ссылки в каждом браузере, кроме IE.
// check if link points outside of app - not working in IE
try {
const href = $linkElement.attr('href'),
link = new URL(href, window.location);
if (window.location.host === link.host) {
// same app
} else {
// points outside
}
} catch (e) { // in case IE happens}