使用 javascript 跳锚

我有一个经常会被发现的问题。问题在于,没有任何地方可以找到一个明确的解决方案。

关于锚,我有两个问题。

主要目标应该是得到一个漂亮的干净的网址,没有任何散列在它同时使用锚跳转到一个页面。

所以锚的结构是:

<ul>
<li><a href="#one">One</a></li>
<li><a href="#two">Two</a></li>
<li><a href="#three">Three</a></li>
</ul>


<div class="wrap">
<a name="one">text 1</a>
<a name="two">text 2</a>
<a name="three" class="box">text 3</a>
</div>

好的,如果你点击其中一个链接,网址会自动变成

Www.domain.com/page#1

最终,这应该是公正的:

Www.domain.com/page

目前为止,一切顺利。现在的第二件事情是,当你搜索互联网上的问题,你会发现 javascript作为一个解决方案。

我发现了这个函数:

function jumpto(anchor){
window.location.href = "#"+anchor;
}

并调用该函数:

<a onclick="jumpto('one');">One</a>

什么将是相同的像以前。它将添加散列到网址。我还添加了

<a onclick="jumpto('one'); return false;">

所以如果有人能告诉我如何解决这个问题,我会非常感激。

非常感谢。

297689 次浏览

因为当你这么做的时候

window.location.href = "#"+anchor;

你加载一个新页面,你可以这样做:

<a href="#" onclick="jumpTo('one');">One</a>
<a href="#" id="one"></a>


<script>


function getPosition(element){
var e = document.getElementById(element);
var left = 0;
var top = 0;


do{
left += e.offsetLeft;
top += e.offsetTop;
}while(e = e.offsetParent);


return [left, top];
}


function jumpTo(id){
window.scrollTo(getPosition(id));
}


</script>

您可以得到目标元素的坐标,并为其设置滚动位置。但这太复杂了。

这里有一个更懒惰的方法:

function jump(h){
var url = location.href;               //Save down the URL without hash.
location.href = "#"+h;                 //Go to the target element.
history.replaceState(null,null,url);   //Don't like hashes. Changing it back.
}

这使用 replaceState来操作 URL。如果你也想要 对 IE 的支持,那么你必须做 很复杂:

function jump(h){
var top = document.getElementById(h).offsetTop; //Getting Y of target element
window.scrollTo(0, top);                        //Go there directly or some transition
}​

演示: http://jsfiddle.net/DerekL/rEpPA/
另一个过渡是: http://jsfiddle.net/derekl/x3edvp4t/

你也可以使用 .scrollIntoView:

document.getElementById(h).scrollIntoView();   //Even IE6 supports this

(我撒谎了,一点也不复杂)

我认为这是一个简单得多的解决方案:

window.location = (""+window.location).replace(/#[A-Za-z0-9_]*$/,'')+"#myAnchor"

这种方法做 不是重新装弹的网站,并设置了 集中注意力的锚所需的屏幕阅读器。

我有一个提示按钮,点击它打开显示对话,然后我可以写我想搜索,它去的位置在页面上。它使用 javascript 来回答标题。

在 html 文件中:

<button onclick="myFunction()">Load Prompt</button>
<span id="test100"><h4>Hello</h4></span>

在我的.js 文件中

function myFunction() {
var input = prompt("list or new or quit");


while(input !== "quit") {
if(input ==="test100") {
window.location.hash = 'test100';
return;
// else if(input.indexOf("test100") >= 0) {
//   window.location.hash = 'test100';
//   return;
// }
}
}
}

当我将 Test100写入提示符时,它将转到我在 html 文件中放置 span id = “ test100”的位置。

我用谷歌浏览器。

注意: 这个想法来自于在同一个页面上使用

<a href="#test100">Test link</a>

点击就会发送到锚。为了让它工作多次,从经验上需要重新加载页面。

归功于 stackoverflow (也可能是 stackexchange)的人,他们不记得我是如何收集所有零碎信息的。

我没有足够的名声发表评论。

如果锚具有 name但没有设置 id(不推荐这样做,但在野外确实会发生) ,那么选定答案中基于 getElementById()的方法将不起作用。

如果您不能控制文档标记(例如,网络扩展) ,请记住这一点。

所选答案中基于 location的方法也可以用 location.replace简化:

function jump(hash) { location.replace("#" + hash) }

第一个建议的被接受的解决方案并不完全适合我。主要的问题是当它已经跳转到 hash,并且 hash 已经在 url 中时,跳转不会再次发生。为了完整起见,我在这里提出了一个更加详细的解决方案(在 Chrome 和 FF 中测试过)。El 是带锚标记的元素。

        el.addEventListener('click', function(ev) {
ev.preventDefault();
const href = ev.target.getAttribute('href');
const hashIndex = href.indexOf('#');
if (hashIndex !== -1) {
const hashPart = href.substring(hashIndex);
if (location.hash === hashPart) {
document.querySelector(hashPart).scrollIntoView();
}
else {
location.hash = hashPart;
}
}
})