Сделать ссылки привязки к текущей странице при использовании <base> - PullRequest
43 голосов
/ 13 ноября 2011

Когда я использую тег html <base> для определения базового URL-адреса для всех относительных ссылок на странице, якорные ссылки также ссылаются непосредственно на базовый URL-адрес. Есть ли способ установить базовый URL, который позволял бы ссылкам привязки ссылаться на открытую в данный момент страницу?

Например, если у меня есть страница на http://example.com/foo/:


Текущее поведение:

<base href="http://example.com/" />
<a href="bar/">bar</a> <!-- Links to "http://example.com/bar/" -->
<a href="#baz">baz</a> <!-- Links to "http://example.com/#baz" -->

Желаемое поведение:

<base href="http://example.com/" />
<a href="bar/">bar</a> <!-- Links to "http://example.com/bar/" -->
<a href="#baz">baz</a> <!-- Links to "http://example.com/foo/#baz" -->

Ответы [ 10 ]

20 голосов
/ 13 января 2016

Я нашел решение на этом сайте: using-base-href-with-anchors , для которого не требуется jQuery и вот рабочий фрагмент:

<base href="https://example.com/">

<a href="/test">/test</a>
<a href="javascript:;" onclick="document.location.hash='test';">Anchor</a>

или без встроенных js, что-то вроде этого:

document.addEventListener('DOMContentLoaded', function(){
  var es = document.getElementsByTagName('a')
  for(var i=0; i<es.length; i++){
    es[i].addEventListener('click', function(e) {
      e.preventDefault()
      document.location.hash = e.target.getAttribute('href')
    })
  }
})
11 голосов
/ 20 ноября 2013

Опираясь на ответ @James Tomasino, этот ответ несколько более эффективен, устраняет ошибку с двойными хэшами в URL и синтаксическую ошибку.

$(document).ready(function() {
    var pathname = window.location.href.split('#')[0];
    $('a[href^="#"]').each(function() {
        var $this = $(this),
            link = $this.attr('href');
        $this.attr('href', pathname + link);
    });
});
7 голосов
/ 13 ноября 2011

Немного JQuery, вероятно, может помочь вам в этом. Хотя base href работает как нужно, если вы хотите, чтобы ваши ссылки, начинающиеся с якоря (#), были полностью относительными, вы можете перехватить все ссылки, проверить свойство href для тех, которые начинаются с #, и перестроить их, используя текущий URL.

$(document).ready(function () {
    var pathname = window.location.href;
    $('a').each(function () {
       var link = $(this).attr('href');
       if (link.substr(0,1) == "#") {
           $(this).attr('href', pathname + link);
       }
    });
}
2 голосов
/ 19 сентября 2014

Вот еще более короткая версия на основе jQuery, которую я использую в производственной среде, и она хорошо работает для меня.

$().ready(function() {
  $("a[href^='\#']").each(function(){ 
    this.href=location.href.split("#")[0]+'#'+this.href.substr(this.href.indexOf('#')+1);
  });
});
1 голос
/ 15 января 2016

Если вы используете PHP, вы можете использовать следующую функцию для генерации якорных ссылок:

function generateAnchorLink($anchor) {
  $currentURL = "//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";
  $escaped = htmlspecialchars($currentURL, ENT_QUOTES, 'UTF-8');
  return $escaped . '#' . $anchor;
}

Используйте его в таком коде:

<a href="<?php echo generateAnchorLink("baz"); ?>">baz</a>
0 голосов
/ 14 марта 2019

Из приведенного в вопросе примера. Для достижения желаемого поведения я вообще не вижу необходимости использовать «базовый» тег.

Страница находится на http://example.com/foo/

Ниже код даст желаемое поведение:

<a href="/bar/">bar</a> <!-- Links to "http://example.com/bar/" -->
<a href="#baz">baz</a> <!-- Links to "http://example.com/foo/#baz" -->

Хитрость заключается в использовании "/" в начале строки href = "/ bar /".

0 голосов
/ 28 марта 2018

Вы также можете указать абсолютный URL:

<base href="https://example.com/">
<a href="/test#test">test</a>

Вместо этого

<a href="#test">test</a>
0 голосов
/ 04 августа 2017

Если вы используете Angular 2+ (и просто ориентируетесь на Интернет), вы можете сделать это:

component.ts

document = document; // Make document available in template

component.html

<a [href]="document.location.pathname + '#' + anchorName">Click Here</a>
0 голосов
/ 08 декабря 2016

Для предотвращения нескольких # в URL:

         document.addEventListener("click", function(event) {
          var element = event.target;
          if (element.tagName.toLowerCase() == "a" && 
            element.getAttribute("href").indexOf("#") === 0) {
            my_href = location.href + element.getAttribute("href");
            my_href = my_href.replace(/#+/g, '#');
            element.href = my_href;
          }
        });
0 голосов
/ 13 января 2016

Боюсь, что нет способа решить эту проблему без серверного или браузерного скрипта. Вы можете попробовать следующую простую реализацию JavaScript (без jQuery):

document.addEventListener("click", function(event) {
  var element = event.target;
  if (element.tagName.toLowerCase() == "a" && 
      element.getAttribute("href").indexOf("#") === 0) {
    element.href = location.href + element.getAttribute("href");
  }
});
<base href="https://example.com/">

<a href="/test">/test</a>
<a href="#test">#test</a>

Это также работает (в отличие от других ответов) для динамически генерируемых (т.е. созданных с помощью JavaScript) a элементов.

...