|
YAHOO.util.Dom 中的 getXY 函数让开发者充分体验到不同浏览器的 Hack 的乐趣。IE8 即将破壳而出,但愿下面的函数不会又多个 if 判断。getXY 函数使用 匿名函数执行返回 函数(听起来有点拗口,可以参考 圆心 Blog 上的一篇文章)。
var getXY = function() { // 判断是否是 IE if (document.documentElement.getBoundingClientRect) { // 注1 return function(el) { var box = el.getBoundingClientRect();
var rootNode = el.ownerDocument; return [box.left + Y.Dom.getDocumentScrollLeft(rootNode), box.top + Y.Dom.getDocumentScrollTop(rootNode)]; }; } else { return function(el) { var pos = [el.offsetLeft, el.offsetTop]; var parentNode = el.offsetParent;
// 判断是否在 Safari 下,节点是否为 absolute , // 并且父元素是否为 body // 注2. var accountForBody = (isSafari && Y.Dom.getStyle(el, 'position') == 'absolute' && el.offsetParent == el.ownerDocument.body);
// 如果父元素不是自身 if (parentNode != el) { while (parentNode) { pos[0] += parentNode.offsetLeft; pos[1] += parentNode.offsetTop; if (!accountForBody && isSafari && Y.Dom.getStyle(parentNode,'position') == 'absolute' ) { accountForBody = true; } parentNode = parentNode.offsetParent; } }
// 还是针对 Safari 的 if (accountForBody) { //safari doubles in this case pos[0] -= el.ownerDocument.body.offsetLeft; pos[1] -= el.ownerDocument.body.offsetTop; } parentNode = el.parentNode;
// account for any scrolled ancestors while ( parentNode.tagName && !patterns.ROOT_TAG.test(parentNode.tagName) ) { // work around opera inline/table scrollLeft/Top bug // 注3. if (Y.Dom.getStyle(parentNode, 'display') .search(/^inline|table-row.*$/i)) { pos[0] -= parentNode.scrollLeft; pos[1] -= parentNode.scrollTop; }
parentNode = parentNode.parentNode; }
return pos; }; } }() // NOTE: Executing for loadtime branching注. 有关 IE 的 getBoundingClientRect 方法,可以参考这里。 注. Safari 的 BUG,详细情况参见这里。 注. 参见老外的原话(出处): "- Remove parent scroll UNLESS that parent is inline or a table to work around Opera inline/table scrollLeft/Top bug" Fixed in Opera 9.5. (also, Opera 9.5 supports getBoundingClientRect and getClientRects.)最后,有关更多 DOM 的兼容性,可以参看 PPK 的总结(怎么又是他)。
|
|