如何在不触发重新加载的情况下将URL哈希设置为“”((例如example.com/#hash - > example.com/)?

时间:2018-05-30 19:46:46

标签: javascript html hash pushstate scrollspy

我有一个单页网站,我正在使用自制的卷轴。我正在使用history.pushStatehistory.replaceState在滚动到某个部分时设置哈希值。但是,history.pushState(null,null,'')不会更改哈希值。因此,当我从第二部分向上滚动时,该网址仍为example.com/#next-section

如果我使用window.location.hash = '',那么页面会重新加载,奇怪的是即使我试图抓住那个事件。

注意:代码段确实没有显示问题,因为即使在整页模式下也不会出现URL哈希值。

要查看实际操作,我创建了一个repl.it,您必须在运行后将其扩展为整页。

const FOCUS_HEIGHT = 160;
let click = false;

function spyOnScroll()
{
    $('.menu-item').on('click', function(e)
    {
        click = true;
        var hash = $(e.target).attr('href');
        console.log("clicked hash", hash);
        $('html').animate
        (
            {
                scrollTop: $('.anchor' + hash).position().top,
                progress: function(){click = true; console.log("click: " + click)}
            },
            300,
            function()
            {
                click = false;
                console.log("finished. click: " + click);
                $('.menu-item[href="' + hash + '"]').addClass('active'); // make link active
                $('.menu-item[href!="' + hash + '"]').removeClass('active'); //make all others not active
            }
        );
    });

    let nav_links = $('.menu-item');
    console.log("nav links: ", nav_links, typeof nav_links);
    let hashes = Array.from(nav_links).map(link => link.hash);
    hashes = ['', ...hashes];
    console.log("hashes", hashes);
    let anchors = hashes.map((hash) => { return { 'hash': hash, 'position': $('.anchor'+hash).position().top } });
    anchors = [...anchors, {'hash':'none', 'position': Math.pow(10,1000)}];
    anchors = anchors.sort((A, B) => A.position - B.position);
    console.log("anchors", anchors);
    console.log("anchors: ", JSON.stringify(anchors));
    let top_position = anchors[0].position;
    console.log("top position=" + top_position);

    let current_hash = window.location.hash;
    if (current_hash == '')
    {
        current_hash = hashes[0];
    }
    let new_hash = current_hash;
    let current_index = hashes.indexOf(current_hash);
    let new_index = current_index;
    console.log("current hash=" + current_hash, "current_index", current_index);

    $(window).scroll(function(e)
    {
        console.log("scrolling...");

        if (click)
        {
            console.log("scrolled due to click...returning");
            e.preventDefault();
            // click = false;
            return;
        }

        let window_position = $(window).scrollTop();
        current_hash = window.location.hash;

        let deltas = anchors.map(a => a.position - window_position - FOCUS_HEIGHT);
        console.log("deltas: " + JSON.stringify(deltas));
        new_index = anchors.map( a => a.position - window_position -FOCUS_HEIGHT > 0).indexOf(true);
        console.log("current_index", current_index, "new_index", new_index);
        console.log("hashes", hashes);

        if (new_index != current_index)
        {
            new_hash = hashes[new_index -  1];
            current_hash = new_hash;
            current_index = new_index;

            console.log("new hash=" + new_hash + " current hash=" + current_hash);
            $('.menu-item[href="' + new_hash + '"]').addClass('active'); // make link active
            $('.menu-item[href!="' + new_hash + '"]').removeClass('active'); //make all others not active
            console.log("setting hash");
            window.history.pushState(null, null, new_hash);
        }
    });
}

$(window).on('load', spyOnScroll);
.nav {
  position: fixed;
  top: 0px;
}

.main {
  margin: 0 0 0 0;
  height: 2000px;
}

.section {
  height: 500px;
  padding-top: 0em;
}

.section:last-of-type {
    height: 2000px;
}

.menu-item {
  font-size: 2em;
  padding: 0.5em;
  margin: 0.5em;
  color: black;
}

.anchor {
    padding: 0;
    margin: 0;
    height: 0;
}

.active {
  color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="nav">
        <a class="menu-item active" href="">home</a>
        <a class="menu-item" href="#one">one</a>
        <a class="menu-item" href="#two">two</a>
        <a class="menu-item" href="#three">three</a>
    </div>

    <div class="main">
        <div class="section">
            <a class="anchor" id="" name=""></a>
            <h1 id="top">Home</span></h1>
        </div>
        <div class="section">
            <a class="anchor" id="one" name="one"></a>
            <h1>One</span></h1>
        </div>
        <div class="section">
            <a class="anchor" id="two" name="two"></a>
            <h1>Two</span></h1>
        </div>
        <div class="section">
            <a class="anchor" id="three" name="three"></a>
            <h1>Three</span></h1>
        </div>
    </div>

1 个答案:

答案 0 :(得分:0)

我认为您无需刷新即可完全删除它,但请尝试使用window.location.hash = '#'