X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=0.6.x%2Fjs%2F02_dom%2F04_XBoxModel.js;h=d62972be141f2847723798ce4965e1161169b801;hb=b05bf97c1b3b1720e73af54017a48291a364d394;hp=ed00a00b7ff3095c4a1fb78a3ead6e01269394a9;hpb=42e0982b02a99c71702ce8cd8740645aefdc8097;p=pettanr%2FclientJs.git diff --git a/0.6.x/js/02_dom/04_XBoxModel.js b/0.6.x/js/02_dom/04_XBoxModel.js index ed00a00..d62972b 100644 --- a/0.6.x/js/02_dom/04_XBoxModel.js +++ b/0.6.x/js/02_dom/04_XBoxModel.js @@ -10,10 +10,6 @@ var X_Node_BoxModel = { // TODO: offsetLeft, offsetTop の基準位置 X_Node_BoxModel_absoluteOffset; - - - - X_ViewPort[ 'listenOnce' ]( X_EVENT_INIT, function(){ var node = X_Node_systemNode; @@ -65,131 +61,114 @@ X_ViewPort[ 'listenOnce' ]( X_EVENT_INIT, function(){ * getBoxObjectFor * getBoundingClientRect */ -Node.prototype[ 'width' ] = function(){ - if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0; + +function X_Node_BoxModel_mesure( that, name ){ + var flags = that[ '_flags' ], elm; + + if( !that[ '_tag' ] || ( ( flags & X_NodeFlags_IN_TREE ) === 0 ) || ( flags & X_NodeFlags_STYLE_IS_DISPLAY_NONE ) ) return 0; X_Node_updateTimerID && X_Node_startUpdate(); - if( X_UA_DOM.W3C ){ - // TODO width : length + overflow : hidden ならそれを返す? <- block or inline - return this[ '_rawObject' ] ? this[ '_rawObject' ].offsetWidth : 0; - } else - if( X_UA_DOM.IE4 ){ - return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).offsetWidth; - } else { - - }; + elm = that[ '_rawObject' ] || X_Node__ie4getRawNode && X_Node__ie4getRawNode( that ); + return elm ? elm[ name ] : 0; }; -Node.prototype[ 'height' ] = function(){ - if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0; - - X_Node_updateTimerID && X_Node_startUpdate(); +/** + * 要素の幅。elm.offsetWidth + * @alias Node.prototype.width + * @return {number} + * @example node.width(); + */ +function X_Node_width(){ + return X_Node_BoxModel_mesure( this, 'offsetWidth' ); - if( X_UA_DOM.W3C ){ - // this[ 'css' ]( X_Node_CSS_Unit.px, 'height' ); - return this[ '_rawObject' ] ? this[ '_rawObject' ].offsetHeight : 0; - } else - if( X_UA_DOM.IE4 ){ - return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).offsetHeight; - } else { - - }; + // TODO width : length + overflow : hidden ならそれを返す? <- block or inline + // TODO TextNode どうする? + //if( X_UA_DOM.IE4 ) return elm ? elm.style.pixelWidth : 0; + //return elm ? elm.offsetWidth : 0; }; -Node.prototype[ 'clientWidth' ] = function(){ - if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0; - - X_Node_updateTimerID && X_Node_startUpdate(); +/** + * 要素の高さ。elm.offsetHeight + * @alias Node.prototype.height + * @return {number} + * @example node.height(); + */ +function X_Node_height(){ + return X_Node_BoxModel_mesure( this, 'offsetHeight' ); - if( X_UA_DOM.W3C ){ - // this[ 'css' ]( X_Node_CSS_Unit.px, 'width' ); - return this[ '_rawObject' ] ? this[ '_rawObject' ].clientWidth : 0; - } else - if( X_UA_DOM.IE4 ){ - return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).clientWidth; - } else { - - }; + // this[ 'css' ]( X_Node_CSS_Unit.px, 'height' ); + //if( X_UA_DOM.IE4 ) return elm ? elm.style.pixelHeight : 0; + //return elm ? elm.offsetHeight : 0; }; -Node.prototype[ 'clientHeight' ] = function(){ - if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0; +/** + * 要素のコンテンツ領域の幅。elm.clientWidth + * @alias Node.prototype.clientWidth + * @return {number} + * @example node.clientWidth(); + */ +function X_Node_clientWidth(){ + return X_Node_BoxModel_mesure( this, 'clientWidth' ); - X_Node_updateTimerID && X_Node_startUpdate(); - - if( X_UA_DOM.W3C ){ - // this[ 'css' ]( X_Node_CSS_Unit.px, 'height' ); - return this[ '_rawObject' ] ? this[ '_rawObject' ].clientHeight : 0; - } else - if( X_UA_DOM.IE4 ){ - return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).clientHeight; - } else { - - }; + // this[ 'css' ]( X_Node_CSS_Unit.px, 'width' ); + //return elm ? elm.clientWidth : 0; }; -Node.prototype[ 'scrollWidth' ] = function(){ - if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0; - - X_Node_updateTimerID && X_Node_startUpdate(); +/** + * 要素のコンテンツ領域の高さ。elm.clientHeight + * @alias Node.prototype.clientHeight + * @return {number} + * @example node.clientHeight(); + */ +function X_Node_clientHeight(){ + return X_Node_BoxModel_mesure( this, 'clientHeight' ); - if( X_UA_DOM.W3C ){ - // this[ 'css' ]( X_Node_CSS_Unit.px, 'width' ); - return this[ '_rawObject' ] ? this[ '_rawObject' ].scrollWidth : 0; - } else - if( X_UA_DOM.IE4 ){ - return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).scrollWidth; - } else { - - }; + // this[ 'css' ]( X_Node_CSS_Unit.px, 'height' ); + //return elm ? elm.clientHeight : 0; }; -Node.prototype[ 'scrollHeight' ] = function(){ - if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0; - - X_Node_updateTimerID && X_Node_startUpdate(); +/** + * 要素のスクロール領域の幅。elm.scrollWidth + * @alias Node.prototype.scrollWidth + * @return {number} + * @example node.scrollWidth(); + */ +function X_Node_scrollWidth(){ + return X_Node_BoxModel_mesure( this, 'scrollWidth' ); - if( X_UA_DOM.W3C ){ - return this[ '_rawObject' ] ? this[ '_rawObject' ].scrollHeight : 0; - } else - if( X_UA_DOM.IE4 ){ - return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).scrollHeight; - } else { - - }; + // this[ 'css' ]( X_Node_CSS_Unit.px, 'width' ); + //return elm ? elm.scrollWidth : 0; }; -Node.prototype[ 'scrollLeft' ] = function(){ - if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0; - - X_Node_updateTimerID && X_Node_startUpdate(); +/** + * 要素のスクロール領域の高さ。elm.scrollHeight + * @alias Node.prototype.scrollHeight + * @return {number} + * @example node.scrollHeight(); + */ +function X_Node_scrollHeight(){ + return X_Node_BoxModel_mesure( this, 'scrollHeight' ); +}; - if( X_UA_DOM.W3C ){ - // this[ 'css' ]( X_Node_CSS_Unit.px, 'width' ); - return this[ '_rawObject' ] ? this[ '_rawObject' ].scrollLeft : 0; - } else - if( X_UA_DOM.IE4 ){ - return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).scrollLeft; - } else { - - }; +/** + * 要素のスクロール位置。elm.scrollLeft + * @alias Node.prototype.scrollLeft + * @return {number} + * @example node.scrollLeft(); + */ +function X_Node_scrollLeft(){ + return X_Node_BoxModel_mesure( this, 'scrollLeft' ); }; -Node.prototype[ 'scrollTop' ] = function(){ - if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0; - - X_Node_updateTimerID && X_Node_startUpdate(); - - if( X_UA_DOM.W3C ){ - // this[ 'css' ]( X_Node_CSS_Unit.px, 'width' ); - return this[ '_rawObject' ] ? this[ '_rawObject' ].scrollTop : 0; - } else - if( X_UA_DOM.IE4 ){ - return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).scrollTop; - } else { - - }; +/** + * 要素のスクロール位置。elm.scrollTop + * @alias Node.prototype.scrollTop + * @return {number} + * @example node.scrollTop(); + */ +function X_Node_scrollTop(){ + return X_Node_BoxModel_mesure( this, 'scrollTop' ); }; /* -------------------------------------- @@ -198,79 +177,87 @@ Node.prototype[ 'scrollTop' ] = function(){ * position:absolute の指定で自動で top,left を補う必要あり? -> X.Node.CSS * 親要素 border 外側からの値。 IE, Firefox, Safari, Chrome の offsetLeft/Topでは、border 内側なので補正する。 * transformX, Y は加える? アニメーション中は? + * + * http://www.din.or.jp/~hagi3/JavaScript/JSTips/DHTML/ProbIE5.htm#StyleObject */ -// X_Node_CSS_transform, -Node.prototype[ 'x' ] = function(){ - if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0; - - X_Node_updateTimerID && X_Node_startUpdate(); +// TODO X_Node_CSS_transform, + +/** + * 要素の親要素に対する位置。offsetLeft + * @alias Node.prototype.x + * @return {number} + * @example node.x(); + */ +function X_Node_x(){ + return X_Node_BoxModel_mesure( this, 'offsetLeft' ); - if( X_UA_DOM.W3C ){ - // this[ 'css' ]( X_Node_CSS_Unit.px, 'left' ); - // this[ 'css' ]( X_Node_CSS_Unit.px, 'translateX' ); - return this[ '_rawObject' ] ? this[ '_rawObject' ].offsetLeft : 0; - } else - if( X_UA_DOM.IE4 ){ - // pixelLeft http://www.din.or.jp/~hagi3/JavaScript/JSTips/DHTML/ProbIE5.htm - return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).offsetLeft; - } else { - - }; + // this[ 'css' ]( X_Node_CSS_Unit.px, 'left' ); + // this[ 'css' ]( X_Node_CSS_Unit.px, 'translateX' ); + //if( X_UA_DOM.IE4 ) return elm ? elm.style.pixelLeft : 0; + //return elm ? elm.offsetLeft : 0; }; -Node.prototype[ 'y' ] = function(){ - if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0; - - X_Node_updateTimerID && X_Node_startUpdate(); +/** + * 要素の親要素に対する位置。offsetTop + * @alias Node.prototype.y + * @return {number} + * @example node.y(); + */ +function X_Node_y(){ + return X_Node_BoxModel_mesure( this, 'offsetTop' ); - if( X_UA_DOM.W3C ){ - // this[ 'css' ]( X_Node_CSS_Unit.px, 'top' ); - // this[ 'css' ]( X_Node_CSS_Unit.px, 'transisitonY' ); - return this[ '_rawObject' ] ? this[ '_rawObject' ].offsetTop : 0; - } else - if( X_UA_DOM.IE4 ){ - return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).offsetTop; - } else { - - }; + // this[ 'css' ]( X_Node_CSS_Unit.px, 'top' ); + // this[ 'css' ]( X_Node_CSS_Unit.px, 'transisitonY' ); + //if( X_UA_DOM.IE4 ) return elm ? elm.style.pixelTop : 0; + //return elm ? elm.offsetTop : 0; }; -Node.prototype[ 'offset' ] = function( /* xnodeParent */ ){ - - if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return { x : 0, y : 0 }; +/** + * 要素の文書内の位置。 + * @alias Node.prototype.offset + * @return {object} { x: {number}, y : {number} } + * @example node.offset(); + */ +function X_Node_offset(){ + var flags = this[ '_flags' ], + offset = { x : 0, y : 0 }, + obj, parent, elm; - if( X.Doc.body === this || X.Doc.html === this ){ - return { x : 0, y : 0 }; - }; + if( ( ( flags & X_NodeFlags_IN_TREE ) === 0 ) || ( flags & X_NodeFlags_STYLE_IS_DISPLAY_NONE ) ) return offset; + if( X_Node_body === this || X_Node_html === this ) return offset; + X_Node_updateTimerID && X_Node_startUpdate(); + + elm = this[ '_rawObject' ] || X_Node__ie4getRawNode && X_Node__ie4getRawNode( this ); - if( X_UA_DOM.W3C ){ - return this[ '_rawObject' ] ? X_Node_getPosition( this[ '_rawObject' ] ) : { x : 0, y : 0 }; - } else - if( X_UA_DOM.IE4 ){ - return X_Node_getPosition( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ); - } else { - - }; + return elm ? X_Node_getPosition( elm ) : offset; }; // エレメントの座標取得 ~スクロール要素~ -// http://n-yagi.0r2.net/script/2009/06/post_14.html +// http://n-yagi.0r2.net/script/2009/07/post_16.html + +// TODO getClientRects Safari2- ? //■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ // エレメントの絶対座標を得たい //------------------------------------------------------------------------------ // 座標取得 var X_Node_getPosition = - document.documentElement && document.documentElement.getBoundingClientRect ? - function( el ){ - var pos = el.getBoundingClientRect(), - html = document.documentElement, - body = document.body; - return { x:(pos.left + (body.scrollLeft||html.scrollLeft) - html.clientLeft) - , y:(pos.top + (body.scrollTop||html.scrollTop) - html.clientTop) }; - } : + !X_UA[ 'IE4' ] && document.createElement( 'div' ).getBoundingClientRect ? + ( + document.compatMode === 'CSS1Compat' && !X_UA[ 'Webkit' ] ? function( el ){ + var pos = el.getBoundingClientRect(), + html = X_elmHtml; + return { x:(pos.left + html.scrollLeft - html.clientLeft) + , y:(pos.top + html.scrollTop - html.clientTop) }; + } : + function( el ){ + var pos = el.getBoundingClientRect(); + return { x:(pos.left + window.pageXOffset) + , y:(pos.top + window.pageYOffset) }; + } + ) : X_UA[ 'Opera' ] < 10 ? function( el ){ var ex = 0; @@ -290,7 +277,7 @@ var X_Node_getPosition = var ey = 0; // var el = target; - var bd = document.body; + var bd = X_elmBody; do {