使用<base />时,使锚链接指向当前页面

时间:2011-11-13 01:16:34

标签: html href

当我使用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" -->

12 个答案:

答案 0 :(得分:20)

我在这个网站上找到了一个解决方案:using-base-href-with-anchors,它不需要jQuery,这是一个工作片段:

&#13;
&#13;
<base href="https://example.com/">

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

或没有内联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')
    })
  }
})

答案 1 :(得分:11)

基于@James Tomasino的回答,这个有点效率更高,解决了网址中出现双重哈希的错误以及语法错误。

$(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);
    });
});

答案 2 :(得分:7)

一点点jQuery可能会帮助你。尽管base href正在按预期工作,但如果希望以锚(#)开头的链接完全相对,则可以劫持所有链接,检查href属性以查找以#开头的属性,并使用当前URL重建它们。 / p>

$(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);
       }
    });
}

答案 3 :(得分:2)

这是我在生产环境中使用的更短的基于jQuery的版本,它对我来说效果很好。

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

答案 4 :(得分:1)

如果您使用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>

答案 5 :(得分:0)

我担心没有任何服务器端或浏览器端脚本就无法解决这个问题。您可以尝试以下纯JavaScript(不带jQuery)实现:

&#13;
&#13;
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");
  }
});
&#13;
<base href="https://example.com/">

<a href="/test">/test</a>
<a href="#test">#test</a>
&#13;
&#13;
&#13;

它也可以(与其他答案不同)动态生成(即使用JavaScript创建)a元素。

答案 6 :(得分:0)

防止网址中出现多个#:

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

答案 7 :(得分:0)

您还可以提供绝对网址:

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

而不是这个

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

答案 8 :(得分:0)

从问题中给出的示例开始。要实现所需的行为,我根本不需要使用“基本”标签。

页面位于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 /”的开头使用“ /”。

答案 9 :(得分:0)

您可以在链接的标记内使用一些javascript代码。

<span onclick="javascript:var mytarget=((document.location.href.indexOf('#')==-1)? document.location.href + '#destination_anchor' : document.location.href);document.location.href=mytarget;return false;" style="display:inline-block;border:1px solid;border-radius:0.3rem"
 >Text of link</span>

用户单击时如何工作?

  1. 首先,它检查URL中是否已存在锚点(#)。在“?”之前测试条件标志。这是为了避免在用户再次单击相同链接时在URL中两次添加锚,因为重定向将无法进行。
  2. 如果现有URL中有尖号(#),则将锚添加到锚上,并将结果保存在mytarget变量中。否则,请保持页面URL不变。
  3. 最后,转到mytarget变量存储的(已修改或未更改的)URL。

您也可以使用<span>甚至<div>标记代替<a>。 我建议避免使用<a>,以避免在禁用或无法正常运行JavaScript的情况下进行任何不必要的重定向,并通过一些CSS样式使<a>标签的外观更加生动。 即使如此,如果您仍想使用<a>标签,请不要忘记在JavaScript末尾添加return false;并像这样<a onclick="here the javascript;return false;" href="javascript:return false;">...</a>设置href属性。

答案 10 :(得分:-1)

如果你正在使用Angular 2+(并且只是定位网络),你可以这样做:

component.ts

#!/bin/bash

while read oldrev newrev refname
do
    branch=$(git rev-parse --symbolic --abbrev-ref $refname)
    if [ -n "$branch" ] && [ "master" == "$branch" ]; then
       working_tree="/path/to/working/dir"
       GIT_WORK_TREE=$working_tree git checkout $branch -f
       GIT_WORK_TREE=$working_tree git pull
       if [ <error conditional> ]
           echo "error message"
           exit 1
       fi
    fi
done

component.html

document = document; // Make document available in template

答案 11 :(得分:-1)

我的方法是搜索指向锚点的所有链接,并为它们添加文档URL作为前缀。

这仅需要在初始页面加载时使用javascript,并保留浏览器功能,例如在新标签页中打开链接。它也不依赖于jQuery / etc。

document.addEventListener('DOMContentLoaded', function() {
  // get the current URL, removing any fragment
  var documentUrl = document.location.href.replace(/#.*$/, '')

  // iterate through all links
  var linkEls = document.getElementsByTagName('A')
  for (var linkIndex = 0; linkIndex < linkEls.length; linkIndex++) {
    var linkEl = linkEls[linkIndex]
  
    // ignore links that don't begin with #
    if (!linkEl.getAttribute('href').match(/^#/)) {
      continue;
    }
  
    // convert to an absolute url
    linkEl.setAttribute('href', documentUrl + linkEl.getAttribute('href'))
  }

})