Chrome 滚动条冻结现象

上次写过 Chrome 31 的一个离奇 Bug,官方很快就修复了。今天要说的这个现象(暂且称之为现象吧,尽管我觉得是
Bug),很久以来一直存在,我忍了好久,今天终于决定写出来一吐为快。

现象描述

如果页面上,有一部分内容是异步生成的,那么滚动页面到比较靠下的位置后,再刷新页面。这时候,有很大概率页面会出现滚动条冻结的现象:尽管滚动条存在,但无法通过鼠
标滚轮来滚动页面。只能点一下滚动条,或者拖动文字让页面产生滚动,这个冻结现象才会消失。

这个现象描述起来比较复杂,大家可以实际感受下:点这里。

Demo 里,我用 setTimeout 来模拟实际场景里的 Ajax 或者 JsonP 异步加载。

几点说明

我测试了手头的 Chrome 30 和 31,都能稳定复现这个现象,更老版本的 Chrome 我没有测。而其他浏览器,如 Firefox、Safari、IE
各版本都没问题。

Mac 和 Windows 平台下的 Chrome,都存在这个问题,但是现象略有不同: Windows 下是完全冻结;Mac 没有完全冻结,但也挺奇怪的。

另外,顶部那个 fixed 条不是产生这个现象的必要条件,但加上之后,坏的概率比较大,在我这边基本每次都坏。

最后,这个现象产生跟异步生成内容的时机有关。个人猜测,刷新页面后,Chrome
会尽可能尝试还原页面滚动条位置。由于页面一开始没有那么高,所以位置还原失败导致问题的产生。

最后

我尝试页面加载完 setTimeout 一段时间后,先让页面滚动到 (0, 1),再回到 (0, 0),大部分时候可以解决这个问题,但 setTimeout
的时长不好控制。另外,由于这个现象只存在于 Chrome,又很诡异,我也不想专门为解决这个问题引入额外逻辑。大家遇到过这个问题没,怎么处理的?

PS:Chrome 尝试还原滚动条这个看似「人性化」的特性,还会引发其他问题:例如点击我博客页面底部的「Switch
Theme」(注:博客改版,现在没这个功能了),页面刷新后 HTML 内容都变了,但 Chrome
仍然会尝试还原滚动条位置,所以页面被自动定位到中间了,很莫名其妙。

update:直到 Chrome 34.0.1788.0 dev,这个问题依旧没有解决。于是去提了个 bug,已确认。@Jan 19, 2014

专题「浏览器」的其他文章 »

  • iOS 10 Safari 视频播放新政策 (Oct 07, 2016)
  • Chrome 中 scrollingElement 的变化 (Apr 16, 2016)
  • 域名小知识:Public Suffix List (Nov 28, 2015)
  • window.opener.location 安全风险讨论 (Oct 09, 2015)
  • 使用 SRI 增强 localStorage 代码安全 (Sep 26, 2015)
  • Subresource Integrity 介绍 (Sep 23, 2015)
  • 移动 Web 与 JavaScript 定时器 (Mar 27, 2014)
  • Chrome 和 Web Fonts 二三事 (Mar 24, 2014)
  • Webkit 异步加载 CSS 的奇怪现象 (Dec 25, 2013)
  • 小成本实现部分选中的复选框 (Dec 22, 2013)

最多阅读

getAttribute和getAttributeNode 11月以前  |  1541次阅读
一种很帅的JS代码书写方式 11月以前  |  1293次阅读
Web弹出类似Android的Toast的信息提示 11月以前  |  1292次阅读
Chrome 滚动条冻结现象 11月以前  |  1278次阅读
通过jQuery发送ajax请求 11月以前  |  1165次阅读
js为object动态添加属性 11月以前  |  1048次阅读
[小Tip]Webkit下设置hash的一个坑 11月以前  |  977次阅读
AMD 的 CommonJS wrapping 11月以前  |  943次阅读
用Opera Mobile调试手机版网页 11月以前  |  774次阅读
jQuery获取Select选择的Text和Value 10月以前  |  679次阅读
JavaScript跨平台(兼容各个平台)事件 10月以前  |  382次阅读
JavaScript中克隆对象 10月以前  |  348次阅读
用JavaScript添加style节点 10月以前  |  347次阅读
JavaScript字符与ASCII码间的转换 10月以前  |  343次阅读
合并两个Array并去掉重复项 10月以前  |  340次阅读
判断一个对象是否为数组 10月以前  |  330次阅读