项目中最近遇到一个bug,在ios上出现的问题:原页面是在某一块地方滚动,但是改版后,滚动区域改为最外层元素,最外层包裹了一层class为main的div
.main { position: fixed; left: 0; right: 0; bottom: 0; top: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; }
里面是两个元素,上下布局,下面的元素本身是在自己的区域滚动,现在改为跟着上面的元素滚动,到一定距离时把tab固定在顶部。
这个时候有一个tab,每次切换过来时都无法滚动,在本地Chorme浏览器里测试没有问题,但是发布到测试环境, 在ios上就会出现这个问题,试过很多布局和样式,都无法让它滚动,查阅资料后得知:
safari浏览器在渲染页面元素的时候,会预先走webkit浏览器的渲染流程:
- 构建DOM tree
- 构建CSS rule tree
- 根据DOM和CSS tree来构建render tree
- 根据render tree计算页面的layout
- render页面
注意在第三步和第四步的时候,safari浏览器在构建render tree的时候,会预先找到相应的overflow: scroll
元素,在计算页面layout的时候,会计算父元素的高度与子元素的高度,若子元素高于父元素,则在render页面时为其建立一个原生的scrollView。
当子元素的高度是加载后动态计算的时候,safari在加载完成之前是不会在计算在layout之内的,也就是高度为0,则子元素的高度就一定小于父元素的高度,safari不会给父元素一个原生的scrollView。
解决方法
当出现这种问题的时候,给子元素一个height大于等于父元素的高度,让父元素有scrollView。当子元素加载完成时,将包裹元素撑开,父元素便可以自由滚动了。但是截止目前还存在一个问题,就是这个子元素的内容有可能是空的或者高度不足以使父元素滚动,如果设置了height: 100% 这样的情况下也可以滚动,体验上有点问题。这个时候我在子元素完全加载后计算实际高度,再覆盖100%,这样就可以解决这个小问题了。