Html 使用<;时使锚定链接指向当前页面;基地>;

Html 使用<;时使锚定链接指向当前页面;基地>;,html,href,Html,Href,当我使用html标记为页面上的所有相关链接定义基本URL时,锚定链接也直接指向基本URL。有没有一种方法可以设置仍然允许锚链接引用当前打开页面的基本URL 例如,如果我在http://example.com/foo/: 当前行为: <base href="http://example.com/" /> <a href="bar/">bar</a> <!-- Links to "http://example.com/bar/" --> <a

当我使用html
标记为页面上的所有相关链接定义基本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" -->
<a href="/bar/">bar</a> <!-- Links to "http://example.com/bar/" -->
<a href="#baz">baz</a> <!-- Links to "http://example.com/foo/#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/#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" -->
<a href="/bar/">bar</a> <!-- Links to "http://example.com/bar/" -->
<a href="#baz">baz</a> <!-- Links to "http://example.com/foo/#baz" -->

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

在@James-Tomasino-answer的基础上,这一个稍微更有效,解决了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);
    });
});

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

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

如果没有任何服务器端或浏览器端脚本,恐怕无法解决此问题。您可以尝试以下纯JavaScript(不带jQuery)实现:

document.addEventListener(“单击”),函数(事件){
var元素=event.target;
if(element.tagName.toLowerCase()=“a”&&
element.getAttribute(“href”).indexOf(“#”)==0{
element.href=location.href+element.getAttribute(“href”);
}
});

我在这个网站上找到了一个解决方案:它不需要jQuery,下面是一个工作片段:


如果使用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中出现多个#,请执行以下操作:


如果您使用Angular 2+(仅针对web),则可以执行以下操作:

组件技术

document = document; // Make document available in template
component.html

<a [href]="document.location.pathname + '#' + anchorName">Click Here</a>

您还可以提供一个绝对url:

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

而不是这个

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

来自问题中给出的示例。为了实现期望的行为,我认为根本不需要使用“base”标记

页面位于

以下代码将给出所需的行为:

<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" -->
<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/”的开头使用“/”

您可以在链接的标记中使用一些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>
链接的文本
当用户点击时,它是如何工作的

  • 首先,它检查锚(#)是否已经存在于URL中。在“?”符号之前测试条件。这是为了避免在用户再次单击同一链接时在URL中添加两次锚点,因为重定向将不起作用
  • 如果现有URL中有锐符号(#),则会将锚添加到该URL中,并将结果保存在
    mytarget
    变量中。否则,保持页面URL不变
  • 最后,转到
    mytarget
    变量存储的(已修改或未更改的)URL

  • 除了
    ,您还可以使用
    甚至

    ,我的方法是搜索指向锚定的所有链接,并在它们前面加上文档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'))
      }
    
    })
    
    document.addEventListener('DOMContentLoaded',function(){
    //获取当前URL,删除任何片段
    var documentUrl=document.location.href.replace(/#.*$/,“”)
    //遍历所有链接
    var linkEls=document.getElementsByTagName('A')
    对于(var linkIndex=0;linkIndex
    您使用的是服务器端编程语言吗?您可以在链接中动态内联当前请求URI。另请参见@BalusC I'm not,如果可能的话,我宁愿避免它。好吧,如果一切都是静态的,那么就使用
    。我不得不说这是非常错误的,您将基数设置为
    http://server/
    然后你告诉它导航到
    #baz
    ,它会转到
    http://server/#baz
    ,这就是相对URL的工作原理,这就是使用
    所做的,它改变了相对URL的基础。如果这不是你想要的,那么你的链接不应该是相对的,或者应该是相对于基地的href(
    foo#baz
    )@JuanMendes,如果“foo”是一个未知的URL,那么就应该是相对的。虽然在某些情况下这可能没什么问题,但我正在创建的网站的统计数据可能是禁用了JavaScript(或者不可用)的类型。由于这种情况下唯一的退路是破坏,这似乎有点令人担忧。那么,您最好的选择是使用baseURL的完整相对路径(包括锚定)对所有链接进行编码。为什么这是一种不好的做法?为什么不好有很多原因,其中一些解释是,使用内联javascript是完全有效的——它的存在是有原因的。那份文件中反对它的论点是虚假的。您是否应该将整个大型项目基于内联代码?可能不会。您能否有意使用内联代码并将其作为边缘案例/gotchya的解决方案?绝对地它是HTML规范的一部分是有原因的。由于HTML文档的文件大小,全面禁止内联JS是毫无意义的。如果你把相同的代码放在一个外部JS文件中,客户端仍然下载这些字节。这个解决方案不能很好地降低性能。在禁用Javascript的浏览器上,你的链接将被破坏。为什么要投否决票?它可能并不优雅,但它基本上与这里的其他答案是一样的,这些答案不那么简洁,但已经被投票支持。可能有人投票反对,因为它不适用于任何人