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
13 X_ViewPort[ 'listenOnce' ]( X_EVENT_INIT, function(){
\r
14 var node = X_Node_systemNode;
\r
16 node[ 'cssText' ]( 'width:10px;padding:1px;border:2px solid #0;margin:4px;' );
\r
18 X_Node_BoxModel_defaultBoxModel = node[ 'width' ]() === 10 ?
\r
19 X_Node_BoxModel.BORDER_BOX :
\r
20 X_Node_BoxModel.CONTENT_BOX;
\r
22 if( X_Node_BoxModel_defaultBoxModel === X_Node_BoxModel.CONTENT_BOX ){
\r
23 X_Node_BoxModel_boxSizingEnabled = node[ 'cssText' ]( 'width:10px;padding:1px;border:2px solid #0;margin:4px;' +
\r
24 '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
25 [ 'width' ]() === 10;
\r
29 * 古い Gekco、 Presto、 WebKit では影がレイアウトに影響します。たとえば、width が 100% のボックスに外向きの box-shadow を指定すると、横スクロールバーが表示されてしまいます。
\r
30 * TODO boxShadow が有効な要素に対して offsetWidth 等の補正(?)
\r
32 if( X_Node_CSS_Support[ 'boxShadow' ] &&
\r
34 X_Node_CSS_uncamelize( X_Node_CSS_VENDER_PREFIX[ 'boxShadow' ] ) + ':10px 10px 0 0 #000;width:10px;'
\r
35 )[ 'width' ]() !== 10
\r
37 console.log( node[ 'cssText' ]() + node[ 'width' ]() );
\r
38 X_Node_CSS_Support[ 'boxShadowLayoutBug' ] = true;
\r
46 X_Node_BoxModel_absoluteOffset =
\r
47 node[ 'cssText' ]( 'position:absolute;top:0;left:0;margin:1px;border:2px solid #000;padding:4px;' )
\r
48 [ 'append' ]( '<div></div>' )
\r
50 [ 'cssText' ]( 'position:absolute;top:8px;left:8px;margin:16px;border:32px solid #666;padding:64px;' )
\r
53 node[ 'cssText' ]( '' )[ 'empty' ]();
\r
56 /* --------------------------------------
\r
58 * display:blobk かつ overflow:hidden かつ size(px,em)が設定されていたら、再描画しないでその値を返す
\r
62 * getBoundingClientRect
\r
65 function X_Node_BoxModel_mesure( that, name ){
\r
66 var flags = that[ '_flags' ], elm;
\r
68 if( !that[ '_tag' ] || ( ( flags & X_NodeFlags_IN_TREE ) === 0 ) || ( flags & X_NodeFlags_STYLE_IS_DISPLAY_NONE ) ) return 0;
\r
70 X_Node_updateTimerID && X_Node_startUpdate();
\r
72 elm = that[ '_rawObject' ] || X_Node__ie4getRawNode && X_Node__ie4getRawNode( that );
\r
73 return elm ? elm[ name ] : 0;
\r
77 * 要素の幅。elm.offsetWidth
\r
78 * @alias Node.prototype.width
\r
80 * @example node.width();
\r
82 function X_Node_width(){
\r
83 return X_Node_BoxModel_mesure( this, 'offsetWidth' );
\r
85 // TODO width : length + overflow : hidden ならそれを返す? <- block or inline
\r
86 // TODO TextNode どうする?
\r
87 //if( X_UA_DOM.IE4 ) return elm ? elm.style.pixelWidth : 0;
\r
88 //return elm ? elm.offsetWidth : 0;
\r
92 * 要素の高さ。elm.offsetHeight
\r
93 * @alias Node.prototype.height
\r
95 * @example node.height();
\r
97 function X_Node_height(){
\r
98 return X_Node_BoxModel_mesure( this, 'offsetHeight' );
\r
100 // this[ 'css' ]( X_Node_CSS_Unit.px, 'height' );
\r
101 //if( X_UA_DOM.IE4 ) return elm ? elm.style.pixelHeight : 0;
\r
102 //return elm ? elm.offsetHeight : 0;
\r
106 * 要素のコンテンツ領域の幅。elm.clientWidth
\r
107 * @alias Node.prototype.clientWidth
\r
108 * @return {number}
\r
109 * @example node.clientWidth();
\r
111 function X_Node_clientWidth(){
\r
112 return X_Node_BoxModel_mesure( this, 'clientWidth' );
\r
114 // this[ 'css' ]( X_Node_CSS_Unit.px, 'width' );
\r
115 //return elm ? elm.clientWidth : 0;
\r
119 * 要素のコンテンツ領域の高さ。elm.clientHeight
\r
120 * @alias Node.prototype.clientHeight
\r
121 * @return {number}
\r
122 * @example node.clientHeight();
\r
124 function X_Node_clientHeight(){
\r
125 return X_Node_BoxModel_mesure( this, 'clientHeight' );
\r
127 // this[ 'css' ]( X_Node_CSS_Unit.px, 'height' );
\r
128 //return elm ? elm.clientHeight : 0;
\r
132 * 要素のスクロール領域の幅。elm.scrollWidth
\r
133 * @alias Node.prototype.scrollWidth
\r
134 * @return {number}
\r
135 * @example node.scrollWidth();
\r
137 function X_Node_scrollWidth(){
\r
138 return X_Node_BoxModel_mesure( this, 'scrollWidth' );
\r
140 // this[ 'css' ]( X_Node_CSS_Unit.px, 'width' );
\r
141 //return elm ? elm.scrollWidth : 0;
\r
145 * 要素のスクロール領域の高さ。elm.scrollHeight
\r
146 * @alias Node.prototype.scrollHeight
\r
147 * @return {number}
\r
148 * @example node.scrollHeight();
\r
150 function X_Node_scrollHeight(){
\r
151 return X_Node_BoxModel_mesure( this, 'scrollHeight' );
\r
155 * 要素のスクロール位置。elm.scrollLeft
\r
156 * @alias Node.prototype.scrollLeft
\r
157 * @return {number}
\r
158 * @example node.scrollLeft();
\r
160 function X_Node_scrollLeft(){
\r
161 return X_Node_BoxModel_mesure( this, 'scrollLeft' );
\r
165 * 要素のスクロール位置。elm.scrollTop
\r
166 * @alias Node.prototype.scrollTop
\r
167 * @return {number}
\r
168 * @example node.scrollTop();
\r
170 function X_Node_scrollTop(){
\r
171 return X_Node_BoxModel_mesure( this, 'scrollTop' );
\r
174 /* --------------------------------------
\r
176 * position:absolute かつ x か y が設定されていたら、再描画しないで css オブジェクトから計算した値を返す。 float は?
\r
177 * position:absolute の指定で自動で top,left を補う必要あり? -> X.Node.CSS
\r
178 * 親要素 border 外側からの値。 IE, Firefox, Safari, Chrome の offsetLeft/Topでは、border 内側なので補正する。
\r
179 * transformX, Y は加える? アニメーション中は?
\r
181 * http://www.din.or.jp/~hagi3/JavaScript/JSTips/DHTML/ProbIE5.htm#StyleObject
\r
183 // TODO X_Node_CSS_transform,
\r
186 * 要素の親要素に対する位置。offsetLeft
\r
187 * @alias Node.prototype.x
\r
188 * @return {number}
\r
189 * @example node.x();
\r
191 function X_Node_x(){
\r
192 return X_Node_BoxModel_mesure( this, 'offsetLeft' );
\r
194 // this[ 'css' ]( X_Node_CSS_Unit.px, 'left' );
\r
195 // this[ 'css' ]( X_Node_CSS_Unit.px, 'translateX' );
\r
196 //if( X_UA_DOM.IE4 ) return elm ? elm.style.pixelLeft : 0;
\r
197 //return elm ? elm.offsetLeft : 0;
\r
201 * 要素の親要素に対する位置。offsetTop
\r
202 * @alias Node.prototype.y
\r
203 * @return {number}
\r
204 * @example node.y();
\r
206 function X_Node_y(){
\r
207 return X_Node_BoxModel_mesure( this, 'offsetTop' );
\r
209 // this[ 'css' ]( X_Node_CSS_Unit.px, 'top' );
\r
210 // this[ 'css' ]( X_Node_CSS_Unit.px, 'transisitonY' );
\r
211 //if( X_UA_DOM.IE4 ) return elm ? elm.style.pixelTop : 0;
\r
212 //return elm ? elm.offsetTop : 0;
\r
217 * @alias Node.prototype.offset
\r
218 * @return {object} { x: {number}, y : {number} }
\r
219 * @example node.offset();
\r
221 function X_Node_offset(){
\r
222 var flags = this[ '_flags' ],
\r
223 offset = { x : 0, y : 0 },
\r
226 if( ( ( flags & X_NodeFlags_IN_TREE ) === 0 ) || ( flags & X_NodeFlags_STYLE_IS_DISPLAY_NONE ) ) return offset;
\r
228 if( X_Node_body === this || X_Node_html === this ) return offset;
\r
230 X_Node_updateTimerID && X_Node_startUpdate();
\r
232 elm = this[ '_rawObject' ] || X_Node__ie4getRawNode && X_Node__ie4getRawNode( this );
\r
234 return elm ? X_Node_getPosition( elm ) : offset;
\r
237 // エレメントの座標取得 ~スクロール要素~
\r
238 // http://n-yagi.0r2.net/script/2009/07/post_16.html
\r
240 //■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
\r
242 //------------------------------------------------------------------------------
\r
244 var X_Node_getPosition =
\r
245 !X_UA[ 'IE4' ] && document.createElement( 'div' ).getBoundingClientRect ?
\r
247 document.compatMode === 'CSS1Compat' && !X_UA[ 'Webkit' ] ? function( el ){
\r
248 var pos = el.getBoundingClientRect(),
\r
249 html = document.documentElement;
\r
250 return { x:(pos.left + html.scrollLeft - html.clientLeft)
\r
251 , y:(pos.top + html.scrollTop - html.clientTop) };
\r
254 var pos = el.getBoundingClientRect();
\r
255 return { x:(pos.left + window.pageXOffset)
\r
256 , y:(pos.top + window.pageYOffset) };
\r
259 X_UA[ 'Opera' ] < 10 ?
\r
265 ex += el.offsetLeft;
\r
266 ey += el.offsetTop;
\r
268 while( el = el.offsetParent );
\r
270 return {x:ex,y:ey};
\r
278 var bd = X_elmBody;
\r
282 ex += el.offsetLeft || 0;
\r
283 ey += el.offsetTop || 0;
\r
285 while( el = el.offsetParent );
\r
290 ex -= el.scrollLeft || 0;
\r
291 ey -= el.scrollTop || 0;
\r
292 el = el.parentNode;
\r
296 return {x:ex,y:ey};
\r
299 //■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
\r