У меня есть веб-сайт на одну страницу, на котором я использую самодельный 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>