使用javascript实现锚点跳跃

问题描述 投票:0回答:7

我有一个经常会被发现的问题。问题是找不到明确的解决方案。

我有两个关于锚点的问题。

主要目标应该是在使用锚点跳转页面时获得一个漂亮干净的网址,其中不包含任何哈希值。

所以anchor的结构是:

<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>

会和以前一样吗?它将把哈希值添加到 url 中。我还补充了

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

没有成功。因此,如果有人可以告诉我如何解决这个问题,我真的很感激。

非常感谢。

javascript html function anchor href
7个回答
248
投票

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

这是一种更懒惰的方法:

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

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


22
投票

我认为这是更简单的解决方案:

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

此方法不重新加载网站,并将焦点设置在屏幕阅读器所需的锚点上。


7
投票

我没有足够的代表发表评论。

如果锚点具有

getElementById()
但未设置
name
(不建议这样做,但在野外确实会发生),则所选答案中基于
id
的方法将不起作用。

如果您无法控制文档标记(例如 webextension),需要记住一些事情。

所选答案中基于

location
的方法也可以用
location.replace
来简化:

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

2
投票

因为当你这样做时

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>

2
投票

我有一个提示按钮,单击它会打开显示对话框,然后我可以写下我想要搜索的内容,它会转到页面上的该位置。它使用 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)的人们不记得我是如何收集所有零碎信息的。 ☺


0
投票

第一个建议的已接受解决方案对我来说并不完全有效。主要问题是当它已经跳转到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;
                }
            }
        })

0
投票

这是我发现的最简单的解决方案,也非常强大:

window.location.href = window.location.href.split("#")[0] + "#my-page-anchor";

这个:

  • 允许在 URL 中使用页面锚点,与
    scrollToView
    (对于分析有用)
  • 无论 URL 中当前有多少个哈希(无论是 1 个、无还是 20 个),都可以工作,因此如果单击多次也不会失败
  • 不重新加载页面
© www.soinside.com 2019 - 2024. All rights reserved.