首先,如果您还没有使用base,或者现在可以放弃使用它,请阅读:
这会让您有很多充分的理由三思而后行。故事的寓意:使用base 通常是个坏主意。有充分的理由,而且很有用;在与设计师合作时,我曾多次使用它来获得我可以使用的标记的本地副本,但仍保持与网站资产的连接。但是对于生产现场来说,就太聪明了一半。
此外,这个答案最初是为 different question 写的,它是完全重复的,所以我在这里发布这个,尽管已经有一个非常相似的答案。
您是否可以控制标记,或者您可以使用选择器仅获取您想要影响的元素?你可以:
HTML(注意类truelink。)
<ol>
<li>
<a href="#link1" class="truelink">True Link1</a>
</li>
<li>
<a href="#link2" class="truelink">True Link2</a>
</li>
<li>
<a href="#link3" class="truelink">True Link3</a>
</li>
</ol>
Javascript
window.addEventListener('load', function links(){
var base = document.getElementsByTagName('base')[0],
links = document.getElementsByClassName('truelink'),
l = links.length,
uri = 'http://www.host.tld/path?query=test';
console.log('Base:', base, ', True Links:', links);
console.log('Modifying links in five seconds...');
setTimeout(function go(){
console.log('Modifying links now...');
while (l--){
links[l].href = links[l].href.replace(base.href, uri);
}
console.log('Base: ', base, 'True Links: ', links);
}, 5000);
});
http://jsfiddle.net/M5Hdk/
请记住,此技术演示了使用 document.getElementsByClassName,直到版本 9 才被 IE 支持。如果您必须支持低于 IE9 的版本,请参阅 Jeremy J Starcher 的回答,了解“效率较低”但支持更好的方法.还有document.querySelectorAll,IE8及以上以及所有其他主流浏览器都支持。如果您只需要支持 IE8,我建议您使用它来选择您的链接,而不是 Jeremy 演示的方法。
我还将更改延迟了五秒钟,以便您看到它有效。显然,这对您来说不是必需的(很可能)。
我现在唯一不确定的是我的.replace() 是否总能在所有浏览器中找到要替换的base.href,所以在做之前检测相对 url 的存在可能会更好替换,因此您可以适当地做其他任何事情。有关这个可能的“问题”的一些相关背景,请参阅我的问题,该问题涉及浏览器如何在 DOM 中以不同方式处理 href 属性:
Method for selecting elements in Sizzle using fully-qualified URLs
此外,如果它位于内容之后的内联 script 标记中,或者位于 body 标记的末尾,这可能会最无缝地工作,在这种情况下,您将需要删除 window.addEventListener 部分并替换为自执行函数。
他们是其他选项,都可能有点问题:
- 彻底清除
base 标签。但是,如果您这样做,您首先要检查是否需要手动将 base.href 内容插入链接中,否则我确信事情可能会破裂或变脆。
- 为
a链接添加一个事件监听器,你想使用你的真实链接并以这种方式操作它onclick,只是不要忘记在点击处理函数的末尾return false,所以浏览器不遵循链接。这可能是最无缝的方法,但可能并不适合所有情况。
- 可能还有其他人。
一定要使用真实世界的标记进行测试。base 是一个有点古怪的工具,因此处理它可能会导致不寻常的副作用。 你被警告了。