OSDN Git Service

4ba647889b5023680f9921dd834eb496be862542
[pettanr/clientJs.git] / 0.6.x / js / 02_dom / 04_XBoxModel.js
1 var X_Node_BoxModel = {\r
2         CONTENT_BOX      : 1,\r
3         PADDING_BOX      : 2,\r
4         BORDER_BOX       : 3,\r
5                 \r
6         defaultBoxModel  : 0,\r
7         boxSizingEnabled : false,\r
8         \r
9         // TODO: offsetLeft, offsetTop の基準位置\r
10         absoluteOffset   : 0\r
11 };\r
12 \r
13 \r
14 \r
15 X_ViewPort.listenOnce( X_TEMP.SYSTEM_EVENT_INIT, function(){\r
16         var node = X_Node_systemNode;\r
17         \r
18         node.cssText( 'width:10px;padding:1px;border:2px solid #0;margin:4px;' );\r
19         \r
20         X_Node_BoxModel.defaultBoxModel = node.width() === 10 ?\r
21                 X_Node_BoxModel.BORDER_BOX :\r
22                 X_Node_BoxModel.CONTENT_BOX;\r
23         \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
27                                                                                         .width() === 10;\r
28         };\r
29         \r
30         /*\r
31          * 古い Gekco、 Presto、 WebKit では影がレイアウトに影響します。たとえば、width が 100% のボックスに外向きの box-shadow を指定すると、横スクロールバーが表示されてしまいます。\r
32          * TODO boxShadow が有効な要素に対して offsetWidth 等の補正(?)\r
33          */\r
34         if( X_Node_CSS_Support[ 'boxShadow' ] &&\r
35                 node.cssText(\r
36                         X_Node_CSS_uncamelize( X_Node_CSS_VENDER_PREFIX[ 'boxShadow' ] ) + ':10px 10px 0 0 #000;width:10px;'\r
37                                 ).width() !== 10\r
38          ){\r
39                 console.log( node.cssText() + node.width() );\r
40                 X_Node_CSS_Support[ 'boxShadowLayoutBug' ] = true;\r
41         };\r
42 \r
43         // padding\r
44         // border\r
45         // margin\r
46         // top\r
47 \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
52                         .y();\r
53 \r
54 \r
55         node.cssText( '' ).empty();\r
56 });\r
57 \r
58 /* --------------------------------------\r
59  * Width, Height\r
60  *  display:blobk かつ overflow:hidden かつ size(px,em)が設定されていたら、再描画しないでその値を返す\r
61  *  display:none なら 0\r
62  * \r
63  * getBoxObjectFor\r
64  * getBoundingClientRect\r
65  */\r
66 Node.prototype.width = function(){\r
67         if( ( this._flags & X_Node_State.IN_TREE ) === 0 || this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
68         \r
69         X_Node_updateTimerID && X_Node_startUpdate();\r
70         \r
71         if( X_UA_DOM.W3C ){\r
72                 // TODO width : length + overflow : hidden ならそれを返す? <- block or inline\r
73                 return this._rawObject ? this._rawObject.offsetWidth : 0;\r
74         } else\r
75         if( X_UA_DOM.IE4 ){\r
76                 return ( this._rawObject || X_Node__ie4getRawNode( this ) ).offsetWidth;\r
77         } else {\r
78                 \r
79         };\r
80 };\r
81 \r
82 Node.prototype.height = function(){\r
83         if( ( this._flags & X_Node_State.IN_TREE ) === 0 || this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
84         \r
85         X_Node_updateTimerID && X_Node_startUpdate();\r
86         \r
87         if( X_UA_DOM.W3C ){\r
88                 // this.css( X_Node_CSS_Unit.px, 'height' );\r
89                 return this._rawObject ? this._rawObject.offsetHeight : 0;\r
90         } else\r
91         if( X_UA_DOM.IE4 ){\r
92                 return ( this._rawObject || X_Node__ie4getRawNode( this ) ).offsetHeight;\r
93         } else {\r
94                 \r
95         };\r
96 };\r
97 \r
98 Node.prototype.clientWidth = function(){\r
99         if( ( this._flags & X_Node_State.IN_TREE ) === 0 || this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
100         \r
101         X_Node_updateTimerID && X_Node_startUpdate();\r
102         \r
103         if( X_UA_DOM.W3C ){\r
104                 // this.css( X_Node_CSS_Unit.px, 'width' );\r
105                 return this._rawObject ? this._rawObject.clientWidth : 0;\r
106         } else\r
107         if( X_UA_DOM.IE4 ){\r
108                 return ( this._rawObject || X_Node__ie4getRawNode( this ) ).clientWidth;\r
109         } else {\r
110                 \r
111         };\r
112 };\r
113 \r
114 Node.prototype.clientHeight = function(){\r
115         if( ( this._flags & X_Node_State.IN_TREE ) === 0 || this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
116         \r
117         X_Node_updateTimerID && X_Node_startUpdate();\r
118 \r
119         if( X_UA_DOM.W3C ){\r
120                 // this.css( X_Node_CSS_Unit.px, 'height' );\r
121                 return this._rawObject ? this._rawObject.clientHeight : 0;\r
122         } else\r
123         if( X_UA_DOM.IE4 ){\r
124                 return ( this._rawObject || X_Node__ie4getRawNode( this ) ).clientHeight;\r
125         } else {\r
126                 \r
127         };\r
128 };\r
129 \r
130 Node.prototype.scrollWidth = function(){\r
131         if( ( this._flags & X_Node_State.IN_TREE ) === 0 || this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
132         \r
133         X_Node_updateTimerID && X_Node_startUpdate();\r
134 \r
135         if( X_UA_DOM.W3C ){\r
136                 // this.css( X_Node_CSS_Unit.px, 'width' );\r
137                 return this._rawObject ? this._rawObject.scrollWidth : 0;\r
138         } else\r
139         if( X_UA_DOM.IE4 ){\r
140                 return ( this._rawObject || X_Node__ie4getRawNode( this ) ).scrollWidth;\r
141         } else {\r
142                 \r
143         };\r
144 };\r
145 \r
146 Node.prototype.scrollHeight = function(){\r
147         if( ( this._flags & X_Node_State.IN_TREE ) === 0 || this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
148         \r
149         X_Node_updateTimerID && X_Node_startUpdate();\r
150 \r
151         if( X_UA_DOM.W3C ){\r
152                 return this._rawObject ? this._rawObject.scrollHeight : 0;\r
153         } else\r
154         if( X_UA_DOM.IE4 ){\r
155                 return ( this._rawObject || X_Node__ie4getRawNode( this ) ).scrollHeight;\r
156         } else {\r
157                 \r
158         };\r
159 };\r
160 \r
161 Node.prototype.scrollLeft = function(){\r
162         if( ( this._flags & X_Node_State.IN_TREE ) === 0 || this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
163         \r
164         X_Node_updateTimerID && X_Node_startUpdate();\r
165 \r
166         if( X_UA_DOM.W3C ){\r
167                 // this.css( X_Node_CSS_Unit.px, 'width' );\r
168                 return this._rawObject ? this._rawObject.scrollLeft : 0;\r
169         } else\r
170         if( X_UA_DOM.IE4 ){\r
171                 return ( this._rawObject || X_Node__ie4getRawNode( this ) ).scrollLeft;\r
172         } else {\r
173                 \r
174         };\r
175 };\r
176 \r
177 Node.prototype.scrollTop = function(){\r
178         if( ( this._flags & X_Node_State.IN_TREE ) === 0 || this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
179         \r
180         X_Node_updateTimerID && X_Node_startUpdate();\r
181         \r
182         if( X_UA_DOM.W3C ){\r
183                 // this.css( X_Node_CSS_Unit.px, 'width' );\r
184                 return this._rawObject ? this._rawObject.scrollTop : 0;\r
185         } else\r
186         if( X_UA_DOM.IE4 ){\r
187                 return ( this._rawObject || X_Node__ie4getRawNode( this ) ).scrollTop;\r
188         } else {\r
189                 \r
190         };\r
191 };\r
192 \r
193 /* --------------------------------------\r
194  *  x, y\r
195  *  position:absolute かつ x か y が設定されていたら、再描画しないで css オブジェクトから計算した値を返す。 float は?\r
196  *  position:absolute の指定で自動で top,left を補う必要あり? -> X.Node.CSS\r
197  *  親要素 border 外側からの値。 IE, Firefox, Safari, Chrome の offsetLeft/Topでは、border 内側なので補正する。\r
198  * transformX, Y は加える? アニメーション中は?\r
199  */\r
200 // X_Node_CSS_transform,\r
201 Node.prototype.x = function(){\r
202         if( ( this._flags & X_Node_State.IN_TREE ) === 0 || this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
203         \r
204         X_Node_updateTimerID && X_Node_startUpdate();\r
205         \r
206         if( X_UA_DOM.W3C ){\r
207                 // this.css( X_Node_CSS_Unit.px, 'left' );\r
208                 // this.css( X_Node_CSS_Unit.px, 'translateX' );\r
209                 return this._rawObject ? this._rawObject.offsetLeft : 0;\r
210         } else\r
211         if( X_UA_DOM.IE4 ){\r
212                 // pixelLeft http://www.din.or.jp/~hagi3/JavaScript/JSTips/DHTML/ProbIE5.htm\r
213                 return ( this._rawObject || X_Node__ie4getRawNode( this ) ).offsetLeft;\r
214         } else {\r
215                 \r
216         };\r
217 };\r
218 \r
219 Node.prototype.y = function(){\r
220         if( ( this._flags & X_Node_State.IN_TREE ) === 0 || this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
221         \r
222         X_Node_updateTimerID && X_Node_startUpdate();\r
223         \r
224         if( X_UA_DOM.W3C ){\r
225                 // this.css( X_Node_CSS_Unit.px, 'top' );\r
226                 // this.css( X_Node_CSS_Unit.px, 'transisitonY' );\r
227                 return this._rawObject ? this._rawObject.offsetTop : 0;\r
228         } else\r
229         if( X_UA_DOM.IE4 ){\r
230                 return ( this._rawObject || X_Node__ie4getRawNode( this ) ).offsetTop;          \r
231         } else {\r
232                 \r
233         };\r
234 };\r
235 \r
236 Node.prototype.offset = function( /* xnodeParent */ ){\r
237 \r
238         if( ( this._flags & X_Node_State.IN_TREE ) === 0 || this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return { x : 0, y : 0 };\r
239         \r
240         if( X.Doc.body === this || X.Doc.html === this ){\r
241                 return { x : 0, y : 0 };\r
242         };\r
243         \r
244         X_Node_updateTimerID && X_Node_startUpdate();\r
245         \r
246         if( X_UA_DOM.W3C ){\r
247                 return this._rawObject ? X_Node_getPosition( this._rawObject ) : { x : 0, y : 0 };\r
248         } else\r
249         if( X_UA_DOM.IE4 ){\r
250                 return X_Node_getPosition( this._rawObject || X_Node__ie4getRawNode( this ) );\r
251         } else {\r
252                 \r
253         };\r
254 };\r
255 \r
256 // エレメントの座標取得 ~スクロール要素~\r
257 // http://n-yagi.0r2.net/script/2009/06/post_14.html\r
258 \r
259 //■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■\r
260 //  エレメントの絶対座標を得たい\r
261 //------------------------------------------------------------------------------\r
262 //  座標取得\r
263 var X_Node_getPosition =\r
264         document.documentElement && document.documentElement.getBoundingClientRect ?\r
265                 function( el ){\r
266                 var pos  = el.getBoundingClientRect(),\r
267                         html = document.documentElement,\r
268                         body = document.body;\r
269                 return  {   x:(pos.left +   (body.scrollLeft||html.scrollLeft)  -   html.clientLeft)\r
270                         ,   y:(pos.top  +   (body.scrollTop||html.scrollTop)    -   html.clientTop) };\r
271                 } :\r
272         X.UA.Opera < 10 ?\r
273                 function( el ){\r
274             var ex  =   0;\r
275             var ey  =   0;\r
276             do\r
277             { \r
278                 ex  +=  el.offsetLeft;\r
279                 ey  +=  el.offsetTop;\r
280             }\r
281             while(  el  =   el.offsetParent );\r
282             //\r
283             return  {x:ex,y:ey};\r
284                 } :\r
285                 function(target)\r
286         {\r
287             var ex  =   0;\r
288             var ey  =   0;\r
289             //\r
290             var el  =   target;\r
291             var bd  =   document.body;\r
292             \r
293             do\r
294             { \r
295                 ex  +=  el.offsetLeft   ||  0;\r
296                 ey  +=  el.offsetTop    ||  0;\r
297             }\r
298             while(  el  =   el.offsetParent );\r
299             //  要素内スクロール対応\r
300             el  =   target;\r
301             do\r
302             {\r
303                 ex  -=  el.scrollLeft   ||  0;\r
304                 ey  -=  el.scrollTop    ||  0;\r
305                 el  =   el.parentNode;\r
306             }\r
307             while(  el!=bd  );\r
308             //\r
309             return  {x:ex,y:ey};\r
310         };\r
311 \r
312 //■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■\r
313 \r