javascript YUI 讀碼日記之 YAHOO.util.Dom - Part.4
更新時間:2008年03月22日 14:42:58 作者:
YAHOO.util.Dom 中的 getXY 函數(shù)讓開發(fā)者充分體驗到不同瀏覽器的 Hack 的樂趣。IE8 即將破殼而出,但愿下面的函數(shù)不會又多個 if 判斷。getXY 函數(shù)使用 匿名函數(shù)執(zhí)行返回 函數(shù)(聽起來有點拗口,可以參考 圓心 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 下,節(jié)點是否為 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注. 有關(guān) 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.)最后,有關(guān)更多 DOM 的兼容性,可以參看 PPK 的總結(jié)(怎么又是他)。
// 判斷是否是 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 下,節(jié)點是否為 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注. 有關(guān) 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.)最后,有關(guān)更多 DOM 的兼容性,可以參看 PPK 的總結(jié)(怎么又是他)。
相關(guān)文章
解決extjs在firefox中關(guān)閉窗口再打開后iframe中js函數(shù)訪問不到的問題
最近做ext時遇到一個問題,在firefox中瀏覽ext應(yīng)用,加載后第一次打開一個嵌入iframe的Window時,可以直接通過js代碼來執(zhí)行 iframe中的js函數(shù),但是如果將窗口關(guān)閉后重新再打開,將會拋出異常,說是funcName is not a function2008-11-11
javascript 放大鏡 v1.0 基于Yui2 實現(xiàn)的放大鏡效果
javascript 放大鏡 v1.0 基于Yui2 實現(xiàn)的放大鏡效果代碼。2010-03-03
ext form 表單提交數(shù)據(jù)的方法小結(jié)
Ext 表單提交數(shù)據(jù)的三種方法小結(jié),方便利用ext提交數(shù)據(jù)的朋友2008-08-08
學(xué)習(xí)YUI.Ext 第四天--對話框Dialog的使用
學(xué)習(xí)YUI.Ext 第四天--對話框Dialog的使用...2007-03-03
Ext第一周 史上最強學(xué)習(xí)筆記---GridPanel(基礎(chǔ)篇)
我不想教各位新手什么高級技術(shù),因為我也在研究,只是想教大家一個思考的方向,能夠具有舉一反三的能力,能夠真正學(xué)會Ext和開始深入了解。2008-12-12

