-X.Dom.BoxModel = {\r
+var X_Node_BoxModel = {\r
CONTENT_BOX : 1,\r
PADDING_BOX : 2,\r
BORDER_BOX : 3,\r
boxSizingEnabled : false,\r
\r
// TODO: offsetLeft, offsetTop の基準位置\r
- absoluteOffset : 0,\r
- \r
- vScrollbarSize : 0,\r
- hScrollbarSize : 0\r
+ absoluteOffset : 0\r
};\r
\r
\r
\r
-X.ViewPort.listenOnce( X_TEMP.SYSTEM_EVENT_INIT, function(){\r
-\r
- var node = Node._systemNode,\r
- \r
- // http://jsdo.it/imaya/kTYg\r
- body = document.body,\r
- defaultOverflow = document.body.style.overflow,\r
- width, height;\r
-\r
- body.style.overflow = 'hidden';\r
- w = body.clientWidth;\r
- h = body.clientHeight;\r
-\r
- body.style.overflow = 'scroll';\r
- w -= body.clientWidth;\r
- h -= body.clientHeight;\r
-\r
- if( !w ) w = body.offsetWidth - body.clientWidth;\r
- if( !h ) h = body.offsetHeight - body.clientHeight;\r
- body.style.overflow = defaultOverflow; \r
-\r
- X.Dom.BoxModel.vScrollbarSize = w;\r
- X.Dom.BoxModel.hScrollbarSize = h;\r
- if( h <= 0 ){ // ie6, ie11, firefox で 負の値が返る\r
- console.log( 'invalid hScrollbarSize: ' + h );\r
- X.Dom.BoxModel.hScrollbarSize = w;\r
- };\r
- //\r
+X_ViewPort.listenOnce( X_TEMP.SYSTEM_EVENT_INIT, function(){\r
+ var node = X_Node_systemNode;\r
\r
node.cssText( 'width:10px;padding:1px;border:2px solid #0;margin:4px;' );\r
\r
- X.Dom.BoxModel.defaultBoxModel = node.width() === 10 ?\r
- X.Dom.BoxModel.BORDER_BOX :\r
- X.Dom.BoxModel.CONTENT_BOX;\r
+ X_Node_BoxModel.defaultBoxModel = node.width() === 10 ?\r
+ X_Node_BoxModel.BORDER_BOX :\r
+ X_Node_BoxModel.CONTENT_BOX;\r
\r
- if( X.Dom.BoxModel.defaultBoxModel === X.Dom.BoxModel.CONTENT_BOX ){\r
- X.Dom.BoxModel.boxSizingEnabled = node.cssText( 'width:10px;padding:1px;border:2px solid #0;margin:4px;' +\r
+ if( X_Node_BoxModel.defaultBoxModel === X_Node_BoxModel.CONTENT_BOX ){\r
+ X_Node_BoxModel.boxSizingEnabled = node.cssText( 'width:10px;padding:1px;border:2px solid #0;margin:4px;' +\r
'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
.width() === 10;\r
};\r
+ \r
+ /*\r
+ * 古い Gekco、 Presto、 WebKit では影がレイアウトに影響します。たとえば、width が 100% のボックスに外向きの box-shadow を指定すると、横スクロールバーが表示されてしまいます。\r
+ * TODO boxShadow が有効な要素に対して offsetWidth 等の補正(?)\r
+ */\r
+ if( X_Node_CSS_Support[ 'boxShadow' ] &&\r
+ node.cssText(\r
+ X_Node_CSS_uncamelize( X_Node_CSS_VENDER_PREFIX[ 'boxShadow' ] ) + ':10px 10px 0 0 #000;width:10px;'\r
+ ).width() !== 10\r
+ ){\r
+ console.log( node.cssText() + node.width() );\r
+ X_Node_CSS_Support[ 'boxShadowLayoutBug' ] = true;\r
+ };\r
+\r
// padding\r
// border\r
// margin\r
// top\r
\r
- X.Dom.BoxModel.absoluteOffset =\r
+ X_Node_BoxModel.absoluteOffset =\r
node.cssText( 'position:absolute;top:0;left:0;margin:1px;border:2px solid #000;padding:4px;' )\r
.append( '<div></div>' )\r
.firstChild().cssText( 'position:absolute;top:8px;left:8px;margin:16px;border:32px solid #666;padding:64px;' )\r
.y();\r
\r
+\r
node.cssText( '' ).empty();\r
});\r
\r
* getBoundingClientRect\r
*/\r
Node.prototype.width = function(){\r
- if( !this.parent ){// todo : _state で tree に所属しているか?判定\r
- console.log( 'xnode.width() : no parent' );\r
- return 0;\r
- };\r
- Node._body._updateTimerID && Node._body._startUpdate();\r
- if( !this._root ){\r
- console.log( 'xnode.width() : not belong tree.' );\r
- return 0;\r
- };\r
- if( this._state & X_Node_State.DISPLAY_NONE ) return 0;\r
+ if( ( this._flags & X_Node_State.IN_TREE ) === 0 || this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
+ \r
+ X_Node_updateTimerID && X_Node_startUpdate();\r
+ \r
if( X_UA_DOM.W3C ){\r
- // this.css( X.Dom.Style.Unit.px, 'width' );\r
- return this._rawObject.offsetWidth;\r
+ // TODO width : length + overflow : hidden ならそれを返す? <- block or inline\r
+ return this._rawObject ? this._rawObject.offsetWidth : 0;\r
} else\r
if( X_UA_DOM.IE4 ){\r
- return ( this._rawObject || this._ie4getRawNode() ).offsetWidth;\r
+ return ( this._rawObject || X_Node__ie4getRawNode( this ) ).offsetWidth;\r
} else {\r
\r
};\r
};\r
\r
Node.prototype.height = function(){\r
- if( !this.parent ){\r
- console.log( 'xnode.height() : no parent' );\r
- return 0;\r
- };\r
- Node._body._updateTimerID && Node._body._startUpdate();\r
- if( !this._root ){\r
- console.log( 'xnode.height() : not belong tree.' );\r
- return 0;\r
- };\r
- if( this._state & X_Node_State.DISPLAY_NONE ) return 0;\r
+ if( ( this._flags & X_Node_State.IN_TREE ) === 0 || this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
+ \r
+ X_Node_updateTimerID && X_Node_startUpdate();\r
+ \r
if( X_UA_DOM.W3C ){\r
- // this.css( X.Dom.Style.Unit.px, 'height' );\r
- return this._rawObject.offsetHeight;\r
+ // this.css( X_Node_CSS_Unit.px, 'height' );\r
+ return this._rawObject ? this._rawObject.offsetHeight : 0;\r
} else\r
if( X_UA_DOM.IE4 ){\r
- return ( this._rawObject || this._ie4getRawNode() ).offsetHeight;\r
+ return ( this._rawObject || X_Node__ie4getRawNode( this ) ).offsetHeight;\r
} else {\r
\r
};\r
};\r
\r
Node.prototype.clientWidth = function(){\r
- if( !this.parent ){// todo : _state で tree に所属しているか?判定\r
- console.log( 'xnode.width() : no parent' );\r
- return 0;\r
- };\r
- Node._body._updateTimerID && Node._body._startUpdate();\r
- if( !this._root ){\r
- console.log( 'xnode.width() : not belong tree.' );\r
- return 0;\r
- };\r
- if( this._state & X_Node_State.DISPLAY_NONE ) return 0;\r
+ if( ( this._flags & X_Node_State.IN_TREE ) === 0 || this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
+ \r
+ X_Node_updateTimerID && X_Node_startUpdate();\r
+ \r
if( X_UA_DOM.W3C ){\r
- // this.css( X.Dom.Style.Unit.px, 'width' );\r
- return this._rawObject.clientWidth;\r
+ // this.css( X_Node_CSS_Unit.px, 'width' );\r
+ return this._rawObject ? this._rawObject.clientWidth : 0;\r
} else\r
if( X_UA_DOM.IE4 ){\r
- return ( this._rawObject || this._ie4getRawNode() ).clientWidth;\r
+ return ( this._rawObject || X_Node__ie4getRawNode( this ) ).clientWidth;\r
} else {\r
\r
};\r
};\r
\r
Node.prototype.clientHeight = function(){\r
- if( !this.parent ){\r
- console.log( 'xnode.height() : no parent' );\r
- return 0;\r
- };\r
- Node._body._updateTimerID && Node._body._startUpdate();\r
- if( !this._root ){\r
- console.log( 'xnode.height() : not belong tree.' );\r
- return 0;\r
- };\r
- if( this._state & X_Node_State.DISPLAY_NONE ) return 0;\r
+ if( ( this._flags & X_Node_State.IN_TREE ) === 0 || this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
+ \r
+ X_Node_updateTimerID && X_Node_startUpdate();\r
+\r
if( X_UA_DOM.W3C ){\r
- // this.css( X.Dom.Style.Unit.px, 'height' );\r
- return this._rawObject.clientHeight;\r
+ // this.css( X_Node_CSS_Unit.px, 'height' );\r
+ return this._rawObject ? this._rawObject.clientHeight : 0;\r
} else\r
if( X_UA_DOM.IE4 ){\r
- return ( this._rawObject || this._ie4getRawNode() ).clientHeight;\r
+ return ( this._rawObject || X_Node__ie4getRawNode( this ) ).clientHeight;\r
} else {\r
\r
};\r
};\r
\r
Node.prototype.scrollWidth = function(){\r
- if( !this.parent ){// todo : _state で tree に所属しているか?判定\r
- console.log( 'xnode.width() : no parent' );\r
- return 0;\r
- };\r
- Node._body._updateTimerID && Node._body._startUpdate();\r
- if( !this._root ){\r
- console.log( 'xnode.width() : not belong tree.' );\r
- return 0;\r
- };\r
- if( this._state & X_Node_State.DISPLAY_NONE ) return 0;\r
+ if( ( this._flags & X_Node_State.IN_TREE ) === 0 || this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
+ \r
+ X_Node_updateTimerID && X_Node_startUpdate();\r
+\r
if( X_UA_DOM.W3C ){\r
- // this.css( X.Dom.Style.Unit.px, 'width' );\r
- return this._rawObject.scrollWidth;\r
+ // this.css( X_Node_CSS_Unit.px, 'width' );\r
+ return this._rawObject ? this._rawObject.scrollWidth : 0;\r
} else\r
if( X_UA_DOM.IE4 ){\r
- return ( this._rawObject || this._ie4getRawNode() ).scrollWidth;\r
+ return ( this._rawObject || X_Node__ie4getRawNode( this ) ).scrollWidth;\r
} else {\r
\r
};\r
};\r
\r
Node.prototype.scrollHeight = function(){\r
- if( !this.parent ){\r
- console.log( 'xnode.height() : no parent' );\r
- return 0;\r
- };\r
- Node._body._updateTimerID && Node._body._startUpdate();\r
- if( !this._root ){\r
- console.log( 'xnode.height() : not belong tree.' );\r
- return 0;\r
- };\r
- if( this._state & X_Node_State.DISPLAY_NONE ) return 0;\r
+ if( ( this._flags & X_Node_State.IN_TREE ) === 0 || this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
+ \r
+ X_Node_updateTimerID && X_Node_startUpdate();\r
+\r
if( X_UA_DOM.W3C ){\r
- // this.css( X.Dom.Style.Unit.px, 'height' );\r
- return this._rawObject.scrollHeight;\r
+ return this._rawObject ? this._rawObject.scrollHeight : 0;\r
} else\r
if( X_UA_DOM.IE4 ){\r
- return ( this._rawObject || this._ie4getRawNode() ).scrollHeight;\r
+ return ( this._rawObject || X_Node__ie4getRawNode( this ) ).scrollHeight;\r
} else {\r
\r
};\r
};\r
\r
Node.prototype.scrollLeft = function(){\r
- if( !this.parent ){// todo : _state で tree に所属しているか?判定\r
- console.log( 'xnode.scrollLeft() : no parent' );\r
- return 0;\r
- };\r
- Node._body._updateTimerID && Node._body._startUpdate();\r
- if( !this._root ){\r
- console.log( 'xnode.scrollLeft() : not belong tree.' );\r
- return 0;\r
- };\r
- if( this._state & X_Node_State.DISPLAY_NONE ) return 0;\r
+ if( ( this._flags & X_Node_State.IN_TREE ) === 0 || this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
+ \r
+ X_Node_updateTimerID && X_Node_startUpdate();\r
+\r
if( X_UA_DOM.W3C ){\r
- // this.css( X.Dom.Style.Unit.px, 'width' );\r
- return this._rawObject.scrollLeft;\r
+ // this.css( X_Node_CSS_Unit.px, 'width' );\r
+ return this._rawObject ? this._rawObject.scrollLeft : 0;\r
} else\r
if( X_UA_DOM.IE4 ){\r
- return ( this._rawObject || this._ie4getRawNode() ).scrollLeft;\r
+ return ( this._rawObject || X_Node__ie4getRawNode( this ) ).scrollLeft;\r
} else {\r
\r
};\r
};\r
\r
Node.prototype.scrollTop = function(){\r
- if( !this.parent ){// todo : _state で tree に所属しているか?判定\r
- console.log( 'xnode.scrollTop() : no parent' );\r
- return 0;\r
- };\r
- Node._body._updateTimerID && Node._body._startUpdate();\r
- if( !this._root ){\r
- console.log( 'xnode.scrollTop() : not belong tree.' );\r
- return 0;\r
- };\r
- if( this._state & X_Node_State.DISPLAY_NONE ) return 0;\r
+ if( ( this._flags & X_Node_State.IN_TREE ) === 0 || this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
+ \r
+ X_Node_updateTimerID && X_Node_startUpdate();\r
+ \r
if( X_UA_DOM.W3C ){\r
- // this.css( X.Dom.Style.Unit.px, 'width' );\r
- return this._rawObject.scrollTop;\r
+ // this.css( X_Node_CSS_Unit.px, 'width' );\r
+ return this._rawObject ? this._rawObject.scrollTop : 0;\r
} else\r
if( X_UA_DOM.IE4 ){\r
- return ( this._rawObject || this._ie4getRawNode() ).scrollTop;\r
+ return ( this._rawObject || X_Node__ie4getRawNode( this ) ).scrollTop;\r
} else {\r
\r
};\r
/* --------------------------------------\r
* x, y\r
* position:absolute かつ x か y が設定されていたら、再描画しないで css オブジェクトから計算した値を返す。 float は?\r
- * position:absolute の指定で自動で top,left を補う必要あり? -> X.Dom.Style\r
+ * position:absolute の指定で自動で top,left を補う必要あり? -> X.Node.CSS\r
* 親要素 border 外側からの値。 IE, Firefox, Safari, Chrome の offsetLeft/Topでは、border 内側なので補正する。\r
* transformX, Y は加える? アニメーション中は?\r
*/\r
-// X.Dom.Style.transform,\r
+// X_Node_CSS_transform,\r
Node.prototype.x = function(){\r
- if( !this.parent ){\r
- console.log( 'xnode.x() : no parent' );\r
- return 0;\r
- };\r
- Node._body._updateTimerID && Node._body._startUpdate();\r
- if( !this._root ){\r
- console.log( 'xnode.x() : not belong tree.' );\r
- return 0;\r
- };\r
- if( this._state & X_Node_State.DISPLAY_NONE ) return 0;\r
+ if( ( this._flags & X_Node_State.IN_TREE ) === 0 || this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
+ \r
+ X_Node_updateTimerID && X_Node_startUpdate();\r
+ \r
if( X_UA_DOM.W3C ){\r
- // this.css( X.Dom.Style.Unit.px, 'left' );\r
- // this.css( X.Dom.Style.Unit.px, 'translateX' );\r
- return this._rawObject.offsetLeft;\r
+ // this.css( X_Node_CSS_Unit.px, 'left' );\r
+ // this.css( X_Node_CSS_Unit.px, 'translateX' );\r
+ return this._rawObject ? this._rawObject.offsetLeft : 0;\r
} else\r
if( X_UA_DOM.IE4 ){\r
- return ( this._rawObject || this._ie4getRawNode() ).offsetLeft;\r
+ // pixelLeft http://www.din.or.jp/~hagi3/JavaScript/JSTips/DHTML/ProbIE5.htm\r
+ return ( this._rawObject || X_Node__ie4getRawNode( this ) ).offsetLeft;\r
} else {\r
\r
};\r
};\r
\r
Node.prototype.y = function(){\r
- if( !this.parent ){\r
- console.log( 'xnode.y() : no parent' );\r
- return 0;\r
- };\r
- Node._body._updateTimerID && Node._body._startUpdate();\r
- if( !this._root ){\r
- console.log( 'xnode.y() : not belong tree.' );\r
- return 0;\r
- };\r
- if( this._state & X_Node_State.DISPLAY_NONE ) return 0;\r
+ if( ( this._flags & X_Node_State.IN_TREE ) === 0 || this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return 0;\r
+ \r
+ X_Node_updateTimerID && X_Node_startUpdate();\r
+ \r
if( X_UA_DOM.W3C ){\r
- // this.css( X.Dom.Style.Unit.px, 'top' );\r
- // this.css( X.Dom.Style.Unit.px, 'transisitonY' );\r
- return this._rawObject.offsetTop;\r
+ // this.css( X_Node_CSS_Unit.px, 'top' );\r
+ // this.css( X_Node_CSS_Unit.px, 'transisitonY' );\r
+ return this._rawObject ? this._rawObject.offsetTop : 0;\r
} else\r
if( X_UA_DOM.IE4 ){\r
- return ( this._rawObject || this._ie4getRawNode() ).offsetTop; \r
+ return ( this._rawObject || X_Node__ie4getRawNode( this ) ).offsetTop; \r
} else {\r
\r
};\r
};\r
\r
Node.prototype.offset = function( /* xnodeParent */ ){\r
- var x = 0, y = 0, elm;\r
+\r
+ if( ( this._flags & X_Node_State.IN_TREE ) === 0 || this._flags & X_Node_State.STYLE_IS_DISPLAY_NONE ) return { x : 0, y : 0 };\r
\r
- if( !this.parent ){\r
- console.log( 'xnode.offset() : no parent' );\r
- return { x : 0, y : 0 };\r
- };\r
- Node._body._updateTimerID && Node._body._startUpdate();\r
- if( !this._root ){\r
- console.log( 'xnode.offset() : not belong tree.' );\r
+ if( X.Doc.body === this || X.Doc.html === this ){\r
return { x : 0, y : 0 };\r
};\r
- if( this._state & X_Node_State.DISPLAY_NONE ) return 0;\r
\r
- if( X.Dom.Node._body === this || X.Dom.Node._html === this ){\r
- return { x : 0, y : 0 };\r
- };\r
+ X_Node_updateTimerID && X_Node_startUpdate();\r
\r
if( X_UA_DOM.W3C ){\r
- elm = this._rawObject;\r
+ return this._rawObject ? X_Node_getPosition( this._rawObject ) : { x : 0, y : 0 };\r
} else\r
if( X_UA_DOM.IE4 ){\r
- elm = this._rawObject || this._ie4getRawNode(); \r
+ return X_Node_getPosition( this._rawObject || X_Node__ie4getRawNode( this ) );\r
} else {\r
\r
};\r
- \r
- while( elm && elm !== document.body ){\r
- x += elm.offsetLeft;\r
- y += elm.offsetTop;\r
- elm = elm.offsetParent || elm.parentNode || elm.parentElement;\r
- };\r
- return { x : x, y : y };\r
};\r
+\r
+// エレメントの座標取得 ~スクロール要素~\r
+// http://n-yagi.0r2.net/script/2009/06/post_14.html\r
+\r
+//■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■\r
+// エレメントの絶対座標を得たい\r
+//------------------------------------------------------------------------------\r
+// 座標取得\r
+var X_Node_getPosition =\r
+ document.documentElement && document.documentElement.getBoundingClientRect ?\r
+ function( el ){\r
+ var pos = el.getBoundingClientRect(),\r
+ html = document.documentElement,\r
+ body = document.body;\r
+ return { x:(pos.left + (body.scrollLeft||html.scrollLeft) - html.clientLeft)\r
+ , y:(pos.top + (body.scrollTop||html.scrollTop) - html.clientTop) };\r
+ } :\r
+ X.UA.Opera < 10 ?\r
+ function( el ){\r
+ var ex = 0;\r
+ var ey = 0;\r
+ do\r
+ { \r
+ ex += el.offsetLeft;\r
+ ey += el.offsetTop;\r
+ }\r
+ while( el = el.offsetParent );\r
+ //\r
+ return {x:ex,y:ey};\r
+ } :\r
+ function(target)\r
+ {\r
+ var ex = 0;\r
+ var ey = 0;\r
+ //\r
+ var el = target;\r
+ var bd = document.body;\r
+ \r
+ do\r
+ { \r
+ ex += el.offsetLeft || 0;\r
+ ey += el.offsetTop || 0;\r
+ }\r
+ while( el = el.offsetParent );\r
+ // 要素内スクロール対応\r
+ el = target;\r
+ do\r
+ {\r
+ ex -= el.scrollLeft || 0;\r
+ ey -= el.scrollTop || 0;\r
+ el = el.parentNode;\r
+ }\r
+ while( el!=bd );\r
+ //\r
+ return {x:ex,y:ey};\r
+ };\r
+\r
+//■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■\r
+\r