Как установить хэш URL в "" ((например, example.com/#hash -> example.com/), не вызывая перезагрузку? - PullRequest
0 голосов
/ 30 мая 2018

У меня есть веб-сайт на одну страницу, на котором я использую самодельный scrollspy.Я использую history.pushState или history.replaceState, чтобы установить хэш при прокрутке до раздела.Однако history.pushState(null,null,'') не меняет хеш.Поэтому, когда я прокручиваю вверх из второго раздела, URL-адрес по-прежнему 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 голосов
/ 30 мая 2018

Не думаю, что вы можете полностью удалить его без обновления, но попробуйте просто использовать window.location.hash = '#'.

...