1 var X_Node_BoxModel = {
\r
7 X_Node_BoxModel_defaultBoxModel,
\r
9 X_Node_BoxModel_boxSizingEnabled,
\r
10 // TODO: offsetLeft, offsetTop の基準位置
\r
11 X_Node_BoxModel_absoluteOffset;
\r
17 X_ViewPort[ 'listenOnce' ]( X_EVENT_INIT, function(){
\r
18 var node = X_Node_systemNode;
\r
20 node[ 'cssText' ]( 'width:10px;padding:1px;border:2px solid #0;margin:4px;' );
\r
22 X_Node_BoxModel_defaultBoxModel = node[ 'width' ]() === 10 ?
\r
23 X_Node_BoxModel.BORDER_BOX :
\r
24 X_Node_BoxModel.CONTENT_BOX;
\r
26 if( X_Node_BoxModel_defaultBoxModel === X_Node_BoxModel.CONTENT_BOX ){
\r
27 X_Node_BoxModel_boxSizingEnabled = node[ 'cssText' ]( 'width:10px;padding:1px;border:2px solid #0;margin:4px;' +
\r
28 'box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-o-box-sizing:border-box;-ms-box-sizing:border-box;' )
\r
29 [ 'width' ]() === 10;
\r
33 * 古い Gekco、 Presto、 WebKit では影がレイアウトに影響します。たとえば、width が 100% のボックスに外向きの box-shadow を指定すると、横スクロールバーが表示されてしまいます。
\r
34 * TODO boxShadow が有効な要素に対して offsetWidth 等の補正(?)
\r
36 if( X_Node_CSS_Support[ 'boxShadow' ] &&
\r
38 X_Node_CSS_uncamelize( X_Node_CSS_VENDER_PREFIX[ 'boxShadow' ] ) + ':10px 10px 0 0 #000;width:10px;'
\r
39 )[ 'width' ]() !== 10
\r
41 console.log( node[ 'cssText' ]() + node[ 'width' ]() );
\r
42 X_Node_CSS_Support[ 'boxShadowLayoutBug' ] = true;
\r
50 X_Node_BoxModel_absoluteOffset =
\r
51 node[ 'cssText' ]( 'position:absolute;top:0;left:0;margin:1px;border:2px solid #000;padding:4px;' )
\r
52 [ 'append' ]( '<div></div>' )
\r
54 [ 'cssText' ]( 'position:absolute;top:8px;left:8px;margin:16px;border:32px solid #666;padding:64px;' )
\r
57 node[ 'cssText' ]( '' )[ 'empty' ]();
\r
60 /* --------------------------------------
\r
62 * display:blobk かつ overflow:hidden かつ size(px,em)が設定されていたら、再描画しないでその値を返す
\r
66 * getBoundingClientRect
\r
68 Node.prototype[ 'width' ] = function(){
\r
69 if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;
\r
71 X_Node_updateTimerID && X_Node_startUpdate();
\r
74 // TODO width : length + overflow : hidden ならそれを返す? <- block or inline
\r
75 return this[ '_rawObject' ] ? this[ '_rawObject' ].offsetWidth : 0;
\r
78 return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).offsetWidth;
\r
84 Node.prototype[ 'height' ] = function(){
\r
85 if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;
\r
87 X_Node_updateTimerID && X_Node_startUpdate();
\r
90 // this[ 'css' ]( X_Node_CSS_Unit.px, 'height' );
\r
91 return this[ '_rawObject' ] ? this[ '_rawObject' ].offsetHeight : 0;
\r
94 return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).offsetHeight;
\r
100 Node.prototype[ 'clientWidth' ] = function(){
\r
101 if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;
\r
103 X_Node_updateTimerID && X_Node_startUpdate();
\r
105 if( X_UA_DOM.W3C ){
\r
106 // this[ 'css' ]( X_Node_CSS_Unit.px, 'width' );
\r
107 return this[ '_rawObject' ] ? this[ '_rawObject' ].clientWidth : 0;
\r
109 if( X_UA_DOM.IE4 ){
\r
110 return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).clientWidth;
\r
116 Node.prototype[ 'clientHeight' ] = function(){
\r
117 if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;
\r
119 X_Node_updateTimerID && X_Node_startUpdate();
\r
121 if( X_UA_DOM.W3C ){
\r
122 // this[ 'css' ]( X_Node_CSS_Unit.px, 'height' );
\r
123 return this[ '_rawObject' ] ? this[ '_rawObject' ].clientHeight : 0;
\r
125 if( X_UA_DOM.IE4 ){
\r
126 return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).clientHeight;
\r
132 Node.prototype[ 'scrollWidth' ] = function(){
\r
133 if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;
\r
135 X_Node_updateTimerID && X_Node_startUpdate();
\r
137 if( X_UA_DOM.W3C ){
\r
138 // this[ 'css' ]( X_Node_CSS_Unit.px, 'width' );
\r
139 return this[ '_rawObject' ] ? this[ '_rawObject' ].scrollWidth : 0;
\r
141 if( X_UA_DOM.IE4 ){
\r
142 return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).scrollWidth;
\r
148 Node.prototype[ 'scrollHeight' ] = function(){
\r
149 if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;
\r
151 X_Node_updateTimerID && X_Node_startUpdate();
\r
153 if( X_UA_DOM.W3C ){
\r
154 return this[ '_rawObject' ] ? this[ '_rawObject' ].scrollHeight : 0;
\r
156 if( X_UA_DOM.IE4 ){
\r
157 return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).scrollHeight;
\r
163 Node.prototype[ 'scrollLeft' ] = function(){
\r
164 if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;
\r
166 X_Node_updateTimerID && X_Node_startUpdate();
\r
168 if( X_UA_DOM.W3C ){
\r
169 // this[ 'css' ]( X_Node_CSS_Unit.px, 'width' );
\r
170 return this[ '_rawObject' ] ? this[ '_rawObject' ].scrollLeft : 0;
\r
172 if( X_UA_DOM.IE4 ){
\r
173 return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).scrollLeft;
\r
179 Node.prototype[ 'scrollTop' ] = function(){
\r
180 if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;
\r
182 X_Node_updateTimerID && X_Node_startUpdate();
\r
184 if( X_UA_DOM.W3C ){
\r
185 // this[ 'css' ]( X_Node_CSS_Unit.px, 'width' );
\r
186 return this[ '_rawObject' ] ? this[ '_rawObject' ].scrollTop : 0;
\r
188 if( X_UA_DOM.IE4 ){
\r
189 return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).scrollTop;
\r
195 /* --------------------------------------
\r
197 * position:absolute かつ x か y が設定されていたら、再描画しないで css オブジェクトから計算した値を返す。 float は?
\r
198 * position:absolute の指定で自動で top,left を補う必要あり? -> X.Node.CSS
\r
199 * 親要素 border 外側からの値。 IE, Firefox, Safari, Chrome の offsetLeft/Topでは、border 内側なので補正する。
\r
200 * transformX, Y は加える? アニメーション中は?
\r
202 // X_Node_CSS_transform,
\r
203 Node.prototype[ 'x' ] = function(){
\r
204 if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;
\r
206 X_Node_updateTimerID && X_Node_startUpdate();
\r
208 if( X_UA_DOM.W3C ){
\r
209 // this[ 'css' ]( X_Node_CSS_Unit.px, 'left' );
\r
210 // this[ 'css' ]( X_Node_CSS_Unit.px, 'translateX' );
\r
211 return this[ '_rawObject' ] ? this[ '_rawObject' ].offsetLeft : 0;
\r
213 if( X_UA_DOM.IE4 ){
\r
214 // pixelLeft http://www.din.or.jp/~hagi3/JavaScript/JSTips/DHTML/ProbIE5.htm
\r
215 return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).offsetLeft;
\r
221 Node.prototype[ 'y' ] = function(){
\r
222 if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;
\r
224 X_Node_updateTimerID && X_Node_startUpdate();
\r
226 if( X_UA_DOM.W3C ){
\r
227 // this[ 'css' ]( X_Node_CSS_Unit.px, 'top' );
\r
228 // this[ 'css' ]( X_Node_CSS_Unit.px, 'transisitonY' );
\r
229 return this[ '_rawObject' ] ? this[ '_rawObject' ].offsetTop : 0;
\r
231 if( X_UA_DOM.IE4 ){
\r
232 return ( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) ).offsetTop;
\r
238 Node.prototype[ 'offset' ] = function( /* xnodeParent */ ){
\r
240 if( ( this[ '_flags' ] & X_Node_State.IN_TREE ) === 0 || this[ '_flags' ] & X_Node_State.STYLE_IS_DISPLAY_NONE ) return { x : 0, y : 0 };
\r
242 if( X.Doc.body === this || X.Doc.html === this ){
\r
243 return { x : 0, y : 0 };
\r
246 X_Node_updateTimerID && X_Node_startUpdate();
\r
248 if( X_UA_DOM.W3C ){
\r
249 return this[ '_rawObject' ] ? X_Node_getPosition( this[ '_rawObject' ] ) : { x : 0, y : 0 };
\r
251 if( X_UA_DOM.IE4 ){
\r
252 return X_Node_getPosition( this[ '_rawObject' ] || X_Node__ie4getRawNode( this ) );
\r
258 // エレメントの座標取得 ~スクロール要素~
\r
259 // http://n-yagi.0r2.net/script/2009/06/post_14.html
\r
261 //■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
\r
263 //------------------------------------------------------------------------------
\r
265 var X_Node_getPosition =
\r
266 document.documentElement && document.documentElement.getBoundingClientRect ?
\r
268 var pos = el.getBoundingClientRect(),
\r
269 html = document.documentElement,
\r
270 body = document.body;
\r
271 return { x:(pos.left + (body.scrollLeft||html.scrollLeft) - html.clientLeft)
\r
272 , y:(pos.top + (body.scrollTop||html.scrollTop) - html.clientTop) };
\r
274 X_UA[ 'Opera' ] < 10 ?
\r
280 ex += el.offsetLeft;
\r
281 ey += el.offsetTop;
\r
283 while( el = el.offsetParent );
\r
285 return {x:ex,y:ey};
\r
293 var bd = document.body;
\r
297 ex += el.offsetLeft || 0;
\r
298 ey += el.offsetTop || 0;
\r
300 while( el = el.offsetParent );
\r
305 ex -= el.scrollLeft || 0;
\r
306 ey -= el.scrollTop || 0;
\r
307 el = el.parentNode;
\r
311 return {x:ex,y:ey};
\r
314 //■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
\r