Как автоматически добавить target= "blank" только во внешние ссылки?
Я создаю пользовательскую, отраслевую cms (используя django). В бэкэнде веб-мастера могут указать либо внутреннюю ссылку, например "/ page1", либо внешнюю ссылку для использования для различных элементов навигации по всему веб-сайту (все используют <a>
при отображении) . Проблема в том, что я хотел бы открыть внутренние ссылки на текущей вкладке, но внешние ссылки должны использовать target="_blank"
чтобы открыть новую вкладку или окно.
Как я могу обработать html для этого?
Я бы предпочел серверное решение, но не знаю никакого чистого способа предварительной обработки визуализированных шаблонов в django. Итак, я предполагаю, что самый простой способ сделать это, вероятно, решение javascript/jquery: скрипт, который запускается при загрузке каждой страницы, который добавляет атрибут target="_blank" ко всем внешним ссылкам, но не внутренним ссылкам. Но я не знаю, как это сделать.
7 ответов
Я использую следующие для awhile. Не могу вспомнить, где я нашел его первоначально:
$.expr[':'].external = function(obj){
return !obj.href.match(/^mailto\:/)
&& (obj.hostname != location.hostname)
&& !obj.href.match(/^javascript\:/)
&& !obj.href.match(/^$/)
};
что добавляет :external
селектор jQuery, поэтому вы можете просто сделать:
$('a:external').attr('target', '_blank');
хорошая часть об использовании пользовательского селектора заключается в том, что если вам нужно изменить то, что содержит "внешнюю" ссылку, вы можете изменить ее в одном месте и не беспокоиться об остальной части вашего кода. Например, в моей организации, у нас есть определенные поддомены, которые не являются "внешними", но что мы все еще хочу открыть в новых окнах.
попробуйте что-то вроде
for (var links = document.links, i = 0, a; a = links[i]; i++) {
if (a.host !== location.host) {
a.target = '_blank';
}
}
Не забудьте запустить скрипт к тому времени, когда все ссылки существуют в дереве документов - в window.onload
событие.
вы могли бы сделать что-то вроде этого:
$(document.body).on('mouseover', 'a[target!=_blank]:not(.local)', function (evt) {
var a = $(this);
var href = a.attr('href');
var domain = href.match(/^https?:\/\/([^:\/]+)/);
if (domain && domain[1] && domain[1] !== "yourdomain.com") {
a.attr('target', '_blank');
} else {
a.addClass('local');
}
});
Это будет обрабатывать каждую ссылку, как вы нажимаете на нее, и не должен обрабатывать каждую ссылку более одного раза. Если это должно быть внешним, то target
будет установлен в _blank
и он должен открыться в новом окне. вот рабочий jsfiddle.
обновление: мой метод определения, остается ли ссылка на месте или нет, довольно груб. Метод в ответ более тщательный. Я бы наверное, заменить мой простой матч regex с этот тест вместо.
Я рекомендую вам делать это на стороне сервера. Измените шаблон страницы в зависимости от местоположения ссылки.
вы также можете сделать это:
$("a[href^='http://']").attr("target","_blank");
или
$('a').each(function() {
var a = new RegExp('/' + window.location.host + '/');
if(!a.test(this.href)) {
$(this).click(function(event) {
event.preventDefault();
event.stopPropagation();
window.open(this.href, '_blank');
});
}
});
небольшое изменение кода, которое не дает ошибок, дополнительно = in != =
$.expr[':'].external = function(obj){
return !obj.href.match(/^mailto\:/) && (obj.hostname !== location.hostname) && !obj.href.match(/^javascript\:/) && !obj.href.match(/^$/);
};
$('a:external').attr('target', '_blank');
другое решение JavaScript:
(() => {
(document.querySelectorAll('a')).forEach(link => {
link.hostname !== location.hostname && link.setAttribute('target', '_blank');
})
})();