Safari on iOS 7 中Element.getClientRects的Bug
在Safari浏览器中,DOMElement和Range对象都提供了getBoundingClientRect方法和getClientRects方法。顾名思义,getBoundingClientRect就是获取一个DOMElement或者Range对象的最外围的包围矩形的基于视口左上角的坐标,返回对象类型为ClientRect,getClientRects就是获取一个DOMElement或者Range对象的所有组成矩形的基于视口左上角的坐标,返回的对象类型为ClientRectList。
但是在iOS 7的Safari浏览器中,getClientRect貌似工作的有点儿问题了。
设计一个页面,上面有一个top和left均为100px的DIV,使用绝对定位。然后为了让页面产生滚动,还在比较低的地方再放置一个DIV。然后来检测DOMElement和Range对象的getBoundingClientRect和getClientRects方法的返回值。
当页面没有滚动的时候,一切都是正常的,返回的top都是100,这个是没有问题的。
但是当我向上滚动页面使window.scrollTop大于0的时候,这个结果就有点儿诡异了。在iPhone上的结果是这个样子的:
除了DOMElement.getBoundingClientRect返回了基于视口的坐标值,其他的返回的都是基于整个页面内容的坐标值。
在桌面Safari上,当页面产生滚动的时候,一切都是正确的:
我觉得这个是一个Bug,已经给Apple提交了Bug报告,但是目前尚未收到任何响应。只是用到这个API的同学们注意一下吧。
关键代码:
document.getElementById("d1").addEventListener("click", function(evt) { var s = ""; var rect = this.getBoundingClientRect(); s += "Element.getBoundingClientRect: <br/>left = " + rect.left + ", top = " + rect.top; rect = this.getClientRects()[0]; s += "<br/>Element.getClientRects[0]: <br/>left = " + rect.left + ", top = " + rect.top; var rng = document.createRange(); rng.selectNode(this); rect = rng.getBoundingClientRect(); s += "<br/>Range.getBoundingClientRect: <br/>left = " + rect.left + ", top = " + rect.top; rect = rng.getClientRects()[0]; s += "<br/>Range.getClientRects[0]: <br/>left = " + rect.left + ", top = " + rect.top; this.innerHTML = s; });