X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=0.6.x%2Fjs%2F02_dom%2F04_XBoxModel.js;h=ed00a00b7ff3095c4a1fb78a3ead6e01269394a9;hb=2956150a7c2798e60639b36d69b0c13f6b20a62a;hp=639ed3ab3357feab9ce4aaa43467592af658fe16;hpb=9f5ab564d20a8bd6438693146ae73209c78a2c5e;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 639ed3a..ed00a00 100644 --- a/0.6.x/js/02_dom/04_XBoxModel.js +++ b/0.6.x/js/02_dom/04_XBoxModel.js @@ -1,43 +1,60 @@ var X_Node_BoxModel = { - CONTENT_BOX : 1, - PADDING_BOX : 2, - BORDER_BOX : 3, - - defaultBoxModel : 0, - boxSizingEnabled : false, + CONTENT_BOX : 1, + PADDING_BOX : 2, + BORDER_BOX : 3 + }, + + X_Node_BoxModel_defaultBoxModel, + X_Node_BoxModel_boxSizingEnabled, // TODO: offsetLeft, offsetTop の基準位置 - absoluteOffset : 0 -}; + X_Node_BoxModel_absoluteOffset; + -X_ViewPort.listenOnce( X_TEMP.SYSTEM_EVENT_INIT, function(){ + +X_ViewPort[ 'listenOnce' ]( X_EVENT_INIT, function(){ var node = X_Node_systemNode; - node.cssText( 'width:10px;padding:1px;border:2px solid #0;margin:4px;' ); + node[ 'cssText' ]( 'width:10px;padding:1px;border:2px solid #0;margin:4px;' ); - X_Node_BoxModel.defaultBoxModel = node.width() === 10 ? + X_Node_BoxModel_defaultBoxModel = node[ 'width' ]() === 10 ? X_Node_BoxModel.BORDER_BOX : X_Node_BoxModel.CONTENT_BOX; - if( X_Node_BoxModel.defaultBoxModel === X_Node_BoxModel.CONTENT_BOX ){ - X_Node_BoxModel.boxSizingEnabled = node.cssText( 'width:10px;padding:1px;border:2px solid #0;margin:4px;' + + if( X_Node_BoxModel_defaultBoxModel === X_Node_BoxModel.CONTENT_BOX ){ + X_Node_BoxModel_boxSizingEnabled = node[ 'cssText' ]( 'width:10px;padding:1px;border:2px solid #0;margin:4px;' + 'box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-o-box-sizing:border-box;-ms-box-sizing:border-box;' ) - .width() === 10; + [ 'width' ]() === 10; + }; + + /* + * 古い Gekco、 Presto、 WebKit では影がレイアウトに影響します。たとえば、width が 100% のボックスに外向きの box-shadow を指定すると、横スクロールバーが表示されてしまいます。 + * TODO boxShadow が有効な要素に対して offsetWidth 等の補正(?) + */ + if( X_Node_CSS_Support[ 'boxShadow' ] && + node[ 'cssText' ]( + X_Node_CSS_uncamelize( X_Node_CSS_VENDER_PREFIX[ 'boxShadow' ] ) + ':10px 10px 0 0 #000;width:10px;' + )[ 'width' ]() !== 10 + ){ + console.log( node[ 'cssText' ]() + node[ 'width' ]() ); + X_Node_CSS_Support[ 'boxShadowLayoutBug' ] = true; }; + // padding // border // margin // top - X_Node_BoxModel.absoluteOffset = - node.cssText( 'position:absolute;top:0;left:0;margin:1px;border:2px solid #000;padding:4px;' ) - .append( '
' ) - .firstChild().cssText( 'position:absolute;top:8px;left:8px;margin:16px;border:32px solid #666;padding:64px;' ) - .y(); + X_Node_BoxModel_absoluteOffset = + node[ 'cssText' ]( 'position:absolute;top:0;left:0;margin:1px;border:2px solid #000;padding:4px;' ) + [ 'append' ]( '
' ) + [ 'firstChild' ]() + [ 'cssText' ]( 'position:absolute;top:8px;left:8px;margin:16px;border:32px solid #666;padding:64px;' ) + [ 'y' ](); - node.cssText( '' ).empty(); + node[ 'cssText' ]( '' )[ 'empty' ](); }); /* -------------------------------------- @@ -48,177 +65,128 @@ X_ViewPort.listenOnce( X_TEMP.SYSTEM_EVENT_INIT, function(){ * getBoxObjectFor * getBoundingClientRect */ -Node.prototype.width = function(){ - if( !this.parent ){// todo : _state で tree に所属しているか?判定 - console.log( 'xnode.width() : no parent' ); - return 0; - }; - X_Node_body._updateTimerID && X_Node_startUpdate(); - if( !this._root ){ - console.log( 'xnode.width() : not belong tree.' ); - return 0; - }; - if( this._state & X_Node_State.DISPLAY_NONE ) return 0; +Node.prototype[ 'width' ] = 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.offsetWidth; + // 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; + return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).offsetWidth; } else { }; }; -Node.prototype.height = function(){ - if( !this.parent ){ - console.log( 'xnode.height() : no parent' ); - return 0; - }; - X_Node_body._updateTimerID && X_Node_startUpdate(); - if( !this._root ){ - console.log( 'xnode.height() : not belong tree.' ); - return 0; - }; - if( this._state & X_Node_State.DISPLAY_NONE ) return 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(); + if( X_UA_DOM.W3C ){ - // this.css( X_Node_CSS_Unit.px, 'height' ); - return this._rawObject.offsetHeight; + // 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; + return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).offsetHeight; } else { }; }; -Node.prototype.clientWidth = function(){ - if( !this.parent ){// todo : _state で tree に所属しているか?判定 - console.log( 'xnode.width() : no parent' ); - return 0; - }; - X_Node_body._updateTimerID && X_Node_startUpdate(); - if( !this._root ){ - console.log( 'xnode.width() : not belong tree.' ); - return 0; - }; - if( this._state & X_Node_State.DISPLAY_NONE ) return 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(); + if( X_UA_DOM.W3C ){ - // this.css( X_Node_CSS_Unit.px, 'width' ); - return this._rawObject.clientWidth; + // 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; + return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).clientWidth; } else { }; }; -Node.prototype.clientHeight = function(){ - if( !this.parent ){ - console.log( 'xnode.height() : no parent' ); - return 0; - }; - X_Node_body._updateTimerID && X_Node_startUpdate(); - if( !this._root ){ - console.log( 'xnode.height() : not belong tree.' ); - return 0; - }; - if( this._state & X_Node_State.DISPLAY_NONE ) return 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; + + X_Node_updateTimerID && X_Node_startUpdate(); + if( X_UA_DOM.W3C ){ - // this.css( X_Node_CSS_Unit.px, 'height' ); - return this._rawObject.clientHeight; + // 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; + return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).clientHeight; } else { }; }; -Node.prototype.scrollWidth = function(){ - if( !this.parent ){// todo : _state で tree に所属しているか?判定 - console.log( 'xnode.width() : no parent' ); - return 0; - }; - X_Node_body._updateTimerID && X_Node_startUpdate(); - if( !this._root ){ - console.log( 'xnode.width() : not belong tree.' ); - return 0; - }; - if( this._state & X_Node_State.DISPLAY_NONE ) return 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(); + if( X_UA_DOM.W3C ){ - // this.css( X_Node_CSS_Unit.px, 'width' ); - return this._rawObject.scrollWidth; + // 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; + return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).scrollWidth; } else { }; }; -Node.prototype.scrollHeight = function(){ - if( !this.parent ){ - console.log( 'xnode.height() : no parent' ); - return 0; - }; - X_Node_body._updateTimerID && X_Node_startUpdate(); - if( !this._root ){ - console.log( 'xnode.height() : not belong tree.' ); - return 0; - }; - if( this._state & X_Node_State.DISPLAY_NONE ) return 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(); + if( X_UA_DOM.W3C ){ - // this.css( X_Node_CSS_Unit.px, 'height' ); - return this._rawObject.scrollHeight; + return this[ '_rawObject' ] ? this[ '_rawObject' ].scrollHeight : 0; } else if( X_UA_DOM.IE4 ){ - return ( this._rawObject || X_Node__ie4getRawNode( this ) ).scrollHeight; + return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).scrollHeight; } else { }; }; -Node.prototype.scrollLeft = function(){ - if( !this.parent ){// todo : _state で tree に所属しているか?判定 - console.log( 'xnode.scrollLeft() : no parent' ); - return 0; - }; - X_Node_body._updateTimerID && X_Node_startUpdate(); - if( !this._root ){ - console.log( 'xnode.scrollLeft() : not belong tree.' ); - return 0; - }; - if( this._state & X_Node_State.DISPLAY_NONE ) return 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(); + if( X_UA_DOM.W3C ){ - // this.css( X_Node_CSS_Unit.px, 'width' ); - return this._rawObject.scrollLeft; + // 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; + return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).scrollLeft; } else { }; }; -Node.prototype.scrollTop = function(){ - if( !this.parent ){// todo : _state で tree に所属しているか?判定 - console.log( 'xnode.scrollTop() : no parent' ); - return 0; - }; - X_Node_body._updateTimerID && X_Node_startUpdate(); - if( !this._root ){ - console.log( 'xnode.scrollTop() : not belong tree.' ); - return 0; - }; - if( this._state & X_Node_State.DISPLAY_NONE ) return 0; +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.scrollTop; + // 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; + return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).scrollTop; } else { }; @@ -232,83 +200,116 @@ Node.prototype.scrollTop = function(){ * transformX, Y は加える? アニメーション中は? */ // X_Node_CSS_transform, -Node.prototype.x = function(){ - if( !this.parent ){ - console.log( 'xnode.x() : no parent' ); - return 0; - }; - X_Node_body._updateTimerID && X_Node_startUpdate(); - if( !this._root ){ - console.log( 'xnode.x() : not belong tree.' ); - return 0; - }; - if( this._state & X_Node_State.DISPLAY_NONE ) return 0; +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(); + if( X_UA_DOM.W3C ){ - // this.css( X_Node_CSS_Unit.px, 'left' ); - // this.css( X_Node_CSS_Unit.px, 'translateX' ); - return this._rawObject.offsetLeft; + // 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 ){ - return ( this._rawObject || X_Node__ie4getRawNode( this ) ).offsetLeft; + // pixelLeft http://www.din.or.jp/~hagi3/JavaScript/JSTips/DHTML/ProbIE5.htm + return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).offsetLeft; } else { }; }; -Node.prototype.y = function(){ - if( !this.parent ){ - console.log( 'xnode.y() : no parent' ); - return 0; - }; - X_Node_body._updateTimerID && X_Node_startUpdate(); - if( !this._root ){ - console.log( 'xnode.y() : not belong tree.' ); - return 0; - }; - if( this._state & X_Node_State.DISPLAY_NONE ) return 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(); + if( X_UA_DOM.W3C ){ - // this.css( X_Node_CSS_Unit.px, 'top' ); - // this.css( X_Node_CSS_Unit.px, 'transisitonY' ); - return this._rawObject.offsetTop; + // 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; + return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).offsetTop; } else { }; }; -Node.prototype.offset = function( /* xnodeParent */ ){ - var x = 0, y = 0, elm; - - if( !this.parent ){ - console.log( 'xnode.offset() : no parent' ); - return { x : 0, y : 0 }; - }; - X_Node_body._updateTimerID && X_Node_startUpdate(); - if( !this._root ){ - console.log( 'xnode.offset() : not belong tree.' ); - return { x : 0, y : 0 }; - }; - if( this._state & X_Node_State.DISPLAY_NONE ) return 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 }; if( X.Doc.body === this || X.Doc.html === this ){ return { x : 0, y : 0 }; }; + X_Node_updateTimerID && X_Node_startUpdate(); + if( X_UA_DOM.W3C ){ - elm = this._rawObject; + return this[ '_rawObject' ] ? X_Node_getPosition( this[ '_rawObject' ] ) : { x : 0, y : 0 }; } else if( X_UA_DOM.IE4 ){ - elm = this._rawObject || X_Node__ie4getRawNode( this ); + return X_Node_getPosition( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ); } else { }; - - while( elm && elm !== document.body ){ - x += elm.offsetLeft; - y += elm.offsetTop; - elm = elm.offsetParent || elm.parentNode || elm.parentElement; - }; - return { x : x, y : y }; }; + +// エレメントの座標取得 ~スクロール要素~ +// http://n-yagi.0r2.net/script/2009/06/post_14.html + +//■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ +// エレメントの絶対座標を得たい +//------------------------------------------------------------------------------ +// 座標取得 +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[ 'Opera' ] < 10 ? + function( el ){ + var ex = 0; + var ey = 0; + do + { + ex += el.offsetLeft; + ey += el.offsetTop; + } + while( el = el.offsetParent ); + // + return {x:ex,y:ey}; + } : + function(target) + { + var ex = 0; + var ey = 0; + // + var el = target; + var bd = document.body; + + do + { + ex += el.offsetLeft || 0; + ey += el.offsetTop || 0; + } + while( el = el.offsetParent ); + // 要素内スクロール対応 + el = target; + do + { + ex -= el.scrollLeft || 0; + ey -= el.scrollTop || 0; + el = el.parentNode; + } + while( el!=bd ); + // + return {x:ex,y:ey}; + }; + +//■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ +