[英]Test if links are external with jQuery / javascript?
如何測試鏈接是外部鏈接還是內部鏈接? 請注意:
我懷疑答案就在 location.href 的某處,但解決方案讓我望而卻步。
謝謝!
我知道這篇文章很舊,但它仍然顯示在結果的頂部,所以我想提供另一種方法。 我看到了對錨元素的所有正則表達式檢查,但為什么不只使用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
}
}
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
屬性,因為它們從不包括包含在host
屬性中的port
,如果它不同於 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' );
});
和無 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"));
}
所有不以http
(http://, https://) 開頭的 href 都會被自動視為本地
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/
或者,我們可以使用 vanilla JavaScript href
屬性過濾內部鏈接,該屬性始終是絕對 URL:
$('a').filter( function(i,el) {
return el.href.indexOf(location.protocol+'//'+location.hostname)===0;
})
你忘記了,如果你使用相對路徑怎么辦。
例如:/測試
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
jQuery('a').each(function() { if (this.host !== window.location.host) { console.log(jQuery(this).attr('href')); } });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
const isExternalLink = (url) => {
const tmp = document.createElement('a');
tmp.href = url;
return tmp.host !== window.location.host;
};
// output: true
console.log(isExternalLink('https://foobar.com'));
console.log(isExternalLink('//foobar.com'));
// output: false
console.log(isExternalLink('https://www.stackoverflow.com'));
console.log(isExternalLink('//www.stackoverflow.com'));
console.log(isExternalLink('/foobar'));
console.log(isExternalLink('#foobar'));
使用這種方法的好處是:
hostname
;protocol-relative
URL為了證明這一點,讓我們看一下以下示例:
const lnk = document.createElement('a');
lnk.href = '/foobar';
console.log(lnk.host); // output: 'www.stackoverflow.com'
const lnk = document.createElement('a');
lnk.href = '#foobar';
console.log(lnk.host); // output: 'www.stackoverflow.com'
const lnk = document.createElement('a');
lnk.href = '//www.stackoverflow.com';
console.log(lnk.host); // output: 'www.stackoverflow.com'
/** * 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>
這應該適用於除 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}
是的,我相信您可以通過location.href 檢索當前域名。 另一種可能性是創建一個鏈接元素,將 src 設置為 /,然后檢索規范 URL(如果您使用一個,這將檢索基本 URL,而不一定是域名)。
另請參閱此帖子: 從鏈接的 href 屬性獲取完整的 URI
對於那些感興趣的人,我做了一個 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 分析位,但是現在您可能希望對 url 執行某些操作,因為您知道它是什么類型的鏈接。 只需在三元塊內添加代碼。 如果您只想檢查 1 種類型的鏈接,請用 if 語句替換三元組。
編輯以添加我遇到的問題。 我的一些 href 是“/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();
這並不完全符合問題的“無法對我的域進行硬編碼”的先決條件,但我發現這篇文章正在尋找類似的解決方案,在我的情況下,我可以對我的網址進行硬編碼。 我擔心的是提醒用戶他們將離開網站,但如果他們留在網站上,包括子域(例如:blog.mysite.com,在大多數其他答案中都會失敗),則不會提醒用戶。 所以這是我的解決方案,它從上面投票最多的答案中提取了一些內容:
Array.from( document.querySelectorAll( 'a' ) ).forEach( a => {
a.classList.add( a.hostname.includes("mywebsite.com") ? 'local' : 'external' );
});
$("a").on("click", function(event) {
if ($(this).hasClass('local')) {
return;
} else if ($(this).hasClass('external')) {
if (!confirm("You are about leave the <My Website> website.")) {
event.preventDefault();
}
}
});
這對我有用:
function strip_scheme( url ) {
return url.replace(/^(?:(?:f|ht)tp(?:s)?\:)?\/\/(www\.)?/g, '');
}
function is_link_external( elem ) {
let domain = strip_scheme( elem.attr('href') );
let host = strip_scheme( window.location.host );
return ! domain.indexOf(host) == 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.