web-dev-qa-db-ja.com

<base>を使用するときにアンカーリンクが現在のページを参照するようにする

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" -->
50
Chris Down

私はこのサイトで解決策を見つけました: sing-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')
    })
  }
})
21
davide bubz

@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);
    });
});
11

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);
       }
    });
}
7
James Tomasino

これは、私が本番環境で使用しているさらに短いjQueryベースのバージョンで、私にとってはうまく機能します。

$().ready(function() {
  $("a[href^='\#']").each(function(){ 
    this.href=location.href.split("#")[0]+'#'+this.href.substr(this.href.indexOf('#')+1);
  });
});
2
contendia

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>

絶対URLを指定することもできます。

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

これよりも

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

サーバー側またはブラウザ側のスクリプトがなければ、これを解決する方法はないと思います。次のプレーンな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要素に対しても(他の回答とは異なり)機能します。

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

質問の例から。望ましい動作を実現するために、「base」タグを使用する必要はまったくありません。

ページは 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
Steve Kang