1 var X_Node_BoxModel = {
\r
7 boxSizingEnabled : false,
\r
9 // TODO: offsetLeft, offsetTop の基準位置
\r
15 X_ViewPort.listenOnce( X_TEMP.SYSTEM_EVENT_INIT, function(){
\r
16 var node = X_Node_systemNode;
\r
18 node.cssText( 'width:10px;padding:1px;border:2px solid #0;margin:4px;' );
\r
20 X_Node_BoxModel.defaultBoxModel = node.width() === 10 ?
\r
21 X_Node_BoxModel.BORDER_BOX :
\r
22 X_Node_BoxModel.CONTENT_BOX;
\r
24 if( X_Node_BoxModel.defaultBoxModel === X_Node_BoxModel.CONTENT_BOX ){
\r
25 X_Node_BoxModel.boxSizingEnabled = node.cssText( 'width:10px;padding:1px;border:2px solid #0;margin:4px;' +
\r
26 '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
31 * 古い Gekco、 Presto、 WebKit では影がレイアウトに影響します。たとえば、width が 100% のボックスに外向きの box-shadow を指定すると、横スクロールバーが表示されてしまいます。
\r
32 * TODO boxShadow が有効な要素に対して offsetWidth 等の補正(?)
\r
34 if( X_Node_CSS_Support[ 'boxShadow' ] &&
\r
36 X_Node_CSS_uncamelize( X_Node_CSS_VENDER_PREFIX[ 'boxShadow' ] ) + ':10px 10px 0 0 #000;width:10px;'
\r
39 console.log( node.cssText() + node.width() );
\r
40 X_Node_CSS_Support[ 'boxShadowLayoutBug' ] = true;
\r
48 X_Node_BoxModel.absoluteOffset =
\r
49 node.cssText( 'position:absolute;top:0;left:0;margin:1px;border:2px solid #000;padding:4px;' )
\r
50 .append( '<div></div>' )
\r
51 .firstChild().cssText( 'position:absolute;top:8px;left:8px;margin:16px;border:32px solid #666;padding:64px;' )
\r
55 node.cssText( '' ).empty();
\r
58 /* --------------------------------------
\r
60 * display:blobk かつ overflow:hidden かつ size(px,em)が設定されていたら、再描画しないでその値を返す
\r
64 * getBoundingClientRect
\r
66 Node.prototype.width = function(){
\r
67 if( !this.parent ){// todo : _state で tree に所属しているか?判定
\r
68 console.log( 'xnode.width() : no parent' );
\r
71 X_Node_updateTimerID && X_Node_startUpdate();
\r
72 if( ( this._flags & X_Node_State.IN_TREE ) === 0 ){
\r
73 console.log( 'xnode.width() : not belong tree.' );
\r
76 if( this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;
\r
78 // this.css( X_Node_CSS_Unit.px, 'width' );
\r
79 return this._rawObject.offsetWidth;
\r
82 return ( this._rawObject || X_Node__ie4getRawNode( this ) ).offsetWidth;
\r
88 Node.prototype.height = function(){
\r
90 console.log( 'xnode.height() : no parent' );
\r
93 X_Node_updateTimerID && X_Node_startUpdate();
\r
94 if( ( this._flags & X_Node_State.IN_TREE ) === 0 ){
\r
95 console.log( 'xnode.height() : not belong tree.' );
\r
98 if( this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;
\r
100 // this.css( X_Node_CSS_Unit.px, 'height' );
\r
101 return this._rawObject.offsetHeight;
\r
103 if( X_UA_DOM.IE4 ){
\r
104 return ( this._rawObject || X_Node__ie4getRawNode( this ) ).offsetHeight;
\r
110 Node.prototype.clientWidth = function(){
\r
111 if( !this.parent ){// todo : _state で tree に所属しているか?判定
\r
112 console.log( 'xnode.width() : no parent' );
\r
115 X_Node_updateTimerID && X_Node_startUpdate();
\r
116 if( ( this._flags & X_Node_State.IN_TREE ) === 0 ){
\r
117 console.log( 'xnode.width() : not belong tree.' );
\r
120 if( this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;
\r
121 if( X_UA_DOM.W3C ){
\r
122 // this.css( X_Node_CSS_Unit.px, 'width' );
\r
123 return this._rawObject.clientWidth;
\r
125 if( X_UA_DOM.IE4 ){
\r
126 return ( this._rawObject || X_Node__ie4getRawNode( this ) ).clientWidth;
\r
132 Node.prototype.clientHeight = function(){
\r
133 if( !this.parent ){
\r
134 console.log( 'xnode.height() : no parent' );
\r
137 X_Node_updateTimerID && X_Node_startUpdate();
\r
138 if( ( this._flags & X_Node_State.IN_TREE ) === 0 ){
\r
139 console.log( 'xnode.height() : not belong tree.' );
\r
142 if( this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;
\r
143 if( X_UA_DOM.W3C ){
\r
144 // this.css( X_Node_CSS_Unit.px, 'height' );
\r
145 return this._rawObject.clientHeight;
\r
147 if( X_UA_DOM.IE4 ){
\r
148 return ( this._rawObject || X_Node__ie4getRawNode( this ) ).clientHeight;
\r
154 Node.prototype.scrollWidth = function(){
\r
155 if( !this.parent ){// todo : _state で tree に所属しているか?判定
\r
156 console.log( 'xnode.width() : no parent' );
\r
159 X_Node_updateTimerID && X_Node_startUpdate();
\r
160 if( ( this._flags & X_Node_State.IN_TREE ) === 0 ){
\r
161 console.log( 'xnode.width() : not belong tree.' );
\r
164 if( this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;
\r
165 if( X_UA_DOM.W3C ){
\r
166 // this.css( X_Node_CSS_Unit.px, 'width' );
\r
167 return this._rawObject.scrollWidth;
\r
169 if( X_UA_DOM.IE4 ){
\r
170 return ( this._rawObject || X_Node__ie4getRawNode( this ) ).scrollWidth;
\r
176 Node.prototype.scrollHeight = function(){
\r
177 if( !this.parent ){
\r
178 console.log( 'xnode.height() : no parent' );
\r
181 X_Node_updateTimerID && X_Node_startUpdate();
\r
182 if( ( this._flags & X_Node_State.IN_TREE ) === 0 ){
\r
183 console.log( 'xnode.height() : not belong tree.' );
\r
186 if( this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;
\r
187 if( X_UA_DOM.W3C ){
\r
188 // this.css( X_Node_CSS_Unit.px, 'height' );
\r
189 return this._rawObject.scrollHeight;
\r
191 if( X_UA_DOM.IE4 ){
\r
192 return ( this._rawObject || X_Node__ie4getRawNode( this ) ).scrollHeight;
\r
198 Node.prototype.scrollLeft = function(){
\r
199 if( !this.parent ){// todo : _state で tree に所属しているか?判定
\r
200 console.log( 'xnode.scrollLeft() : no parent' );
\r
203 X_Node_updateTimerID && X_Node_startUpdate();
\r
204 if( ( this._flags & X_Node_State.IN_TREE ) === 0 ){
\r
205 console.log( 'xnode.scrollLeft() : not belong tree.' );
\r
208 if( this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;
\r
209 if( X_UA_DOM.W3C ){
\r
210 // this.css( X_Node_CSS_Unit.px, 'width' );
\r
211 return this._rawObject.scrollLeft;
\r
213 if( X_UA_DOM.IE4 ){
\r
214 return ( this._rawObject || X_Node__ie4getRawNode( this ) ).scrollLeft;
\r
220 Node.prototype.scrollTop = function(){
\r
221 if( !this.parent ){// todo : _state で tree に所属しているか?判定
\r
222 console.log( 'xnode.scrollTop() : no parent' );
\r
225 X_Node_updateTimerID && X_Node_startUpdate();
\r
226 if( ( this._flags & X_Node_State.IN_TREE ) === 0 ){
\r
227 console.log( 'xnode.scrollTop() : not belong tree.' );
\r
230 if( this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;
\r
231 if( X_UA_DOM.W3C ){
\r
232 // this.css( X_Node_CSS_Unit.px, 'width' );
\r
233 return this._rawObject.scrollTop;
\r
235 if( X_UA_DOM.IE4 ){
\r
236 return ( this._rawObject || X_Node__ie4getRawNode( this ) ).scrollTop;
\r
242 /* --------------------------------------
\r
244 * position:absolute かつ x か y が設定されていたら、再描画しないで css オブジェクトから計算した値を返す。 float は?
\r
245 * position:absolute の指定で自動で top,left を補う必要あり? -> X.Node.CSS
\r
246 * 親要素 border 外側からの値。 IE, Firefox, Safari, Chrome の offsetLeft/Topでは、border 内側なので補正する。
\r
247 * transformX, Y は加える? アニメーション中は?
\r
249 // X_Node_CSS_transform,
\r
250 Node.prototype.x = function(){
\r
251 if( !this.parent ){
\r
252 console.log( 'xnode.x() : no parent' );
\r
255 X_Node_updateTimerID && X_Node_startUpdate();
\r
256 if( ( this._flags & X_Node_State.IN_TREE ) === 0 ){
\r
257 console.log( 'xnode.x() : not belong tree.' );
\r
260 if( this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;
\r
261 if( X_UA_DOM.W3C ){
\r
262 // this.css( X_Node_CSS_Unit.px, 'left' );
\r
263 // this.css( X_Node_CSS_Unit.px, 'translateX' );
\r
264 return this._rawObject.offsetLeft;
\r
266 if( X_UA_DOM.IE4 ){
\r
267 return ( this._rawObject || X_Node__ie4getRawNode( this ) ).offsetLeft;
\r
273 Node.prototype.y = function(){
\r
274 if( !this.parent ){
\r
275 console.log( 'xnode.y() : no parent' );
\r
278 X_Node_updateTimerID && X_Node_startUpdate();
\r
279 if( ( this._flags & X_Node_State.IN_TREE ) === 0 ){
\r
280 console.log( 'xnode.y() : not belong tree.' );
\r
283 if( this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;
\r
284 if( X_UA_DOM.W3C ){
\r
285 // this.css( X_Node_CSS_Unit.px, 'top' );
\r
286 // this.css( X_Node_CSS_Unit.px, 'transisitonY' );
\r
287 return this._rawObject.offsetTop;
\r
289 if( X_UA_DOM.IE4 ){
\r
290 return ( this._rawObject || X_Node__ie4getRawNode( this ) ).offsetTop;
\r
296 Node.prototype.offset = function( /* xnodeParent */ ){
\r
297 var x = 0, y = 0, elm;
\r
299 if( !this.parent ){
\r
300 console.log( 'xnode.offset() : no parent' );
\r
301 return { x : 0, y : 0 };
\r
304 if( ( this._flags & X_Node_State.IN_TREE ) === 0 ){
\r
305 console.log( 'xnode.offset() : not belong tree.' );
\r
306 return { x : 0, y : 0 };
\r
308 if( this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return { x : 0, y : 0 };
\r
310 if( X.Doc.body === this || X.Doc.html === this ){
\r
311 return { x : 0, y : 0 };
\r
314 X_Node_updateTimerID && X_Node_startUpdate();
\r
316 if( X_UA_DOM.W3C ){
\r
317 elm = this._rawObject;
\r
319 if( X_UA_DOM.IE4 ){
\r
320 elm = this._rawObject || X_Node__ie4getRawNode( this );
\r
325 return X_Node_getPosition( elm );
\r
328 // エレメントの座標取得 ~スクロール要素~
\r
329 // http://n-yagi.0r2.net/script/2009/06/post_14.html
\r
331 //■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
\r
333 //------------------------------------------------------------------------------
\r
335 var X_Node_getPosition =
\r
336 document.documentElement && document.documentElement.getBoundingClientRect ?
\r
338 var pos = el.getBoundingClientRect(),
\r
339 html = document.documentElement,
\r
340 body = document.body;
\r
341 return { x:(pos.left + (body.scrollLeft||html.scrollLeft) - html.clientLeft)
\r
342 , y:(pos.top + (body.scrollTop||html.scrollTop) - html.clientTop) };
\r
350 ex += el.offsetLeft;
\r
351 ey += el.offsetTop;
\r
353 while( el = el.offsetParent );
\r
355 return {x:ex,y:ey};
\r
363 var bd = document.body;
\r
367 ex += el.offsetLeft || 0;
\r
368 ey += el.offsetTop || 0;
\r
370 while( el = el.offsetParent );
\r
375 ex -= el.scrollLeft || 0;
\r
376 ey -= el.scrollTop || 0;
\r
377 el = el.parentNode;
\r
381 return {x:ex,y:ey};
\r
384 //■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
\r