在一个带有固定顶部菜单和锚点导航的单页布局中,我有一个“scrollspy”,它可以更改滚动时的片段标识符,根据滚动位置为菜单链接提供一个活动类,并使用Velocity.js将滚动动画化到锚点。
不幸的是,当点击浏览器的后退按钮时,它会让我完成滚动方式的所有步骤,这意味着我加载网站并向下滚动和向上滚动一点点,然后频繁地点击后退按钮,浏览器也会向下滚动和向上滚动,但实际上不会转到最后访问的ID或浏览器历史记录。
Here is the jsfiddle.
// jQuery on DOM ready
// In-Page Scroll Animation with VelocityJS
// ------------------------------------------------ //
// https://john-dugan.com/fixed-headers-with-hash-links/
$('.menu-a').on('click', function(e) {
var hash = this.hash,
$hash = $(hash)
addHash = function() {
window.location.hash = hash;
};
$hash.velocity("scroll", { duration: 700, easing: [ .4, .21, .35, 1 ], complete: addHash });
e.preventDefault();
});
// ScrollSpy for Menu items and Fragment Identifier
// ------------------------------------------------ //
// https://jsfiddle.net/mekwall/up4nu/
$menuLink = $('.menu-a')
var lastId,
// Anchors corresponding to menu items
scrollItems = $menuLink.map(function(){
var item = $($(this).attr("href"));
if (item.length) { return item; }
});
$(window).scroll(function(){
// Get container scroll position
var fromTop = $(this).scrollTop()+ 30; // or the value for the #navigation height
// Get id of current scroll item
var cur = scrollItems.map(function(){
if ($(this).offset().top < fromTop)
return this;
});
// Get the id of the current element
cur = cur[cur.length-1];
var id = cur && cur.length ? cur[0].id : "";
if (lastId !== id) {
lastId = id;
// Set/remove active class
$menuLink
.parent().removeClass("active")
.end().filter("[href='#"+id+"']").parent().addClass("active");
}
// If supported by the browser we can also update the URL
// http://codepen.io/grayghostvisuals/pen/EtdwL
if (window.history && window.history.pushState) {
history.pushState("", document.title,'#'+id);
}
});
字符串
使用上面的代码,下面的工作正常:
- 当使用VelocityJS在菜单链接上单击滚动动画时,散列或片段标识符更新良好。
- 活动类在滚动时被赋予相应的菜单链接。
- 当滚动而不是单击菜单链接时,片段标识符也会很好地更新。
问题
**第1部分:**当你在小提琴上滚动一点,然后点击后退按钮,你会看到滚动条以完全相同的方式“移动”,记住已经完成的滚动。
我需要后退按钮像往常一样工作。a)返回浏览器历史记录并返回到您所在的页面/网站; b)当单击锚链接(i),然后单击锚链接(ii),然后单击后退按钮时,页面应返回到锚链接(i)。
**第2部分:**由于history.pushState
在IE8中不支持,我正在寻找一种使用window.location.hash = $(this).attr('id');
的方法。无论我在代码的最后尝试了什么,我都无法让window.location.hash = $(this).attr('id');
工作。我真的不想使用HistoryJS或其他东西,但我有兴趣学习并自己编写它。
除了返回按钮损坏的行为之外,我想要的所有其他行为都已经存在,现在我只需要修复返回按钮的行为。
edit我想我可能已经找到了一个解决方案here,将测试,然后详细回复,如果我得到这个工作。
相关内容:
smooth scrolling and get back button with popState on Firefox - need to click twice的
jQuery in page back button scrolling的
Modifying document.location.hash without page scrolling的
How to Detect Browser Back Button event - Cross Browser的
3条答案
按热度按时间ffx8fchx1#
为了回答你的问题的第一部分,如果你不想污染浏览器的历史记录,你可以使用
history.replaceState()
而不是history.pushState()
。当pushState
更改URL并向浏览器的历史记录添加新条目时,replaceState
更改URL,同时修改当前的历史记录条目,而不是添加新条目。还有一篇很好的文章,包括
pushState
和replaceState
on MDN之间的差异。xfyts7mz2#
对于旧的浏览器,我决定包括https://github.com/devote/HTML5-History-API,并在适当的地方,我得到了所需的行为(或多或少)。
这个答案有:
代码是一个粗略的草图,可能需要一些调整,这只是为了演示的目的。我想我还是一个初学者,请指出明显的错误,这样我就可以从中学习。所有代码片段的来源链接也包括在内。
字符串
CSS格式
型
我也会在适当的时候提供一个jsfiddle。;)
ha5z0ras3#
为了防止浏览器记住滚动位置(如果它不是你的锚链接所在的滚动位置),你必须设置
字符串
参见https://developer.mozilla.org/en-US/docs/Web/API/History/scrollRestoration