有没有可能防止当popstate事件发生时滚动文档的默认行为?
我们的站点使用jQuery动画滚动和History.js,状态变化应该让用户滚动到页面的不同区域,无论是通过pushstate还是popstate。问题是,当发生popstate事件时,浏览器会自动恢复前一个状态的滚动位置。
我尝试使用设置为文档100%宽度和高度的容器元素,并在该容器中滚动内容。我发现这样做的问题是,它看起来不像滚动文档那样流畅;特别是如果使用了大量的css3,比如方框阴影和渐变。
我还尝试在用户启动滚动期间存储文档的滚动位置,并在浏览器滚动页面后恢复它(在popstate上)。这在Firefox12中运行良好,但在Chrome19中,由于页面正在滚动和恢复,因此会出现闪烁。我假设这与scroll和scroll事件之间的延迟有关(其中scroll位置被恢复)。
Firefox在popstate触发之前滚动页面(并触发scroll事件),Chrome首先触发popstate,然后滚动文档。
我见过的所有使用历史API的网站,要么使用与上面类似的解决方案,要么忽略用户后退/前进时滚动位置的变化(例如GitHub)。
有没有可能在popstate事件中完全阻止文档被滚动?
发布于 2012-08-20 19:16:08
在这里,您将不得不使用某种可怕的浏览器嗅探。对于Firefox,我会采用您的解决方案,即存储滚动位置并将其恢复。
根据你的描述,我认为我有一个很好的Webkit解决方案,但我刚刚在Chrome 21中尝试了一下,似乎Chrome首先滚动,然后触发popstate事件,然后触发scroll事件。但作为参考,以下是我的想法:
function noScrollOnce(event) {
event.preventDefault();
document.removeEventListener('scroll', noScrollOnce);
}
window.onpopstate = function () {
document.addEventListener('scroll', noScrollOnce);
};
黑魔法,比如通过移动absolute
定位的元素来假装页面正在滚动,屏幕重绘速度也排除了这种魔力。
所以我99%确定答案是你不能,你将不得不使用你在问题中提到的折衷方案之一。这两种浏览器都会在JavaScript知道之前滚动,所以JavaScript只能在事件发生后才能做出反应。唯一不同的是,火狐只有在Javascript被触发后才会绘制屏幕,这就是为什么火狐有一个可行的解决方案,但WebKit没有。
发布于 2015-12-26 00:18:35
现在你可以做
history.scrollRestoration = 'manual';
这应该会阻止浏览器滚动。这只适用于Chrome46和更高版本,但似乎Firefox也计划支持它
发布于 2014-06-06 21:01:36
解决方案是使用position: fixed
并指定top
等于页面的滚动位置。
下面是一个示例:
$(window).on('popstate', function()
{
$('.yourWrapAroundAllContent').css({
position: 'fixed',
top: -window.scrollY
});
requestAnimationFrame(function()
{
$('.yourWrapAroundAllContent').css({
position: 'static',
top: 0
});
});
});
是的,你得到的是闪烁的滚动条,但它不那么邪恶。
https://stackoverflow.com/questions/10742422
复制相似问题