OSDN Git Service

0c3a820a47839c8a730447597b7a0aa4b9fefd2c
[pettanr/clientJs.git] / 0.6.x / js / dom / 12_XDomEvent.js
1 /**\r
2  * use X.Callback\r
3  * \r
4  * http://d.hatena.ne.jp/uupaa/20100430/1272561922\r
5  * \r
6  */\r
7 \r
8 if( window.addEventListener ){\r
9         X.Dom.Event = function( e, xnode ){\r
10                 //this._event        = e;\r
11                 this.type          = X.Dom.Event.RenameTo[ e.type ] || e.type;\r
12                 \r
13                 //http://www.quirksmode.org/js/events_properties.html\r
14                 this.target        = Node._getXNode( e.target.nodeType === 3 ? e.target.parentNode : e.target );// defeat Safari bug // xnode\r
15                 \r
16                 this.currentTarget = xnode; // xnode\r
17                 this.relatedTarget = Node._getXNode( e.relatedTarget ); // xnode\r
18                 this.eventPhase    = e.eventPhase;\r
19                 \r
20                 this.clientX       = e.clientX;\r
21                 this.clientY       = e.clientY;\r
22                 //this.screenX       = e.screenX;\r
23                 //this.screenY       = e.screenY;\r
24                 this.pageX         = e.pageX;\r
25                 this.pageY         = e.pageY;\r
26                 this.offsetX       = e.offsetX || e.layerX;\r
27                 this.offsetY       = e.offsetY || e.layerY;\r
28                 \r
29                 this.keyCode       = e.keyCode;\r
30                 this.altKey        = e.altKey;\r
31                 this.ctrlKey       = e.ctrlKey;\r
32                 this.shiftKey      = e.shiftKey;\r
33                 \r
34                 // http://www.programming-magic.com/20090127231544/\r
35                 this.which         = e.which || ( e.button + 1 ); // 左:1, 中:2, 右:3\r
36                 \r
37                 // https://developer.mozilla.org/ja/docs/DOM/DOM_event_reference/mousewheel\r
38                 \r
39                 // TODO\r
40                 // https://w3g.jp/blog/tools/wheelevent_crossbrowser\r
41                 // ホイール系イベント2014年版クロスブラウザ\r
42                 if( e.wheelDeltaY !== undefined ){\r
43                         this.wheelDeltaX = e.wheelDeltaX / 12;\r
44                         this.wheelDeltaY = e.wheelDeltaY / 12;\r
45                 } else\r
46                 if( e.wheelDelta !== undefined ){\r
47                         this.wheelDeltaX = this.wheelDeltaY = e.wheelDelta / 12;\r
48                 } else\r
49                 if( e.detail !== undefined ){\r
50                         this.wheelDeltaX = this.wheelDeltaY = - e.detail * 3;\r
51                 } else {\r
52                         this.wheelDeltaX = this.wheelDeltaY = 0;\r
53                 };\r
54                 \r
55                 if( e.constructor === window.TouchEvent ){\r
56                         // TouchEvent\r
57                         this.touches        = e.touches;\r
58                         this.changedTouches = e.changedTouches;\r
59                         this.targetTouches  = e.targetTouches;\r
60                         this.metaKey        = e.metaKey;\r
61                         this.force          = e.force || e.webkitForce || 0;\r
62                 } else\r
63                 if( e.constructor === window.PointerEvent ){\r
64                         // PointerEvent;\r
65                         this.currentPoint  = e.currentPoint;\r
66                         this.width         = e.width;\r
67                         this.height        = e.height;\r
68                         this.timeStamp     = e.timeStamp;\r
69                         this.hwTimestamp   = e.hwTimestamp;\r
70                         this.intermediatePoints = e.intermediatePoints;\r
71                         this.isPrimary     = e.isPrimary;\r
72                         this.pointerId     = e.pointerId;\r
73                         this.pointerType   = e.pointerType;\r
74                         this.pressure      = e.pressure;\r
75                         this.tiltX         = e.tiltX;\r
76                         this.tiltY         = e.tiltY;\r
77                 };\r
78         };\r
79 } else {\r
80         X.Dom.Event = function( e, xnode, element ){\r
81                 var btn;\r
82                 \r
83                 //this._event        = e;\r
84                 this.type          = e.type;\r
85                 this.target        = Node._getXNode( e.srcElement ); // xnode\r
86                 if( this.target && this.target._xnodeType === 3 ) this.target = this.target.parent; // ie4 の fake Textnode がヒットしていないか?\r
87                 this.currentTarget = xnode; // xnode\r
88                 this.relatedTarget = Node._getXNode( e.formElement ? e.formElement : e.toElement ); // xnode\r
89                 this.eventPhase    = e.srcElement === element ? 2: 3;\r
90                 \r
91                 this.clientX       = e.clientX;\r
92                 this.clientY       = e.clientY;\r
93                 //this.screenX       = e.screenX;\r
94                 //this.screenY       = e.screenY;\r
95                 \r
96                 if( X.Dom._root ){ // uuu...\r
97                         \r
98                         this.pageX         = e.clientX + X.Dom._root.scrollLeft;\r
99                         this.pageY         = e.clientY + X.Dom._root.scrollTop;\r
100                         \r
101                         // DOMAssistant 2.8.1\r
102                         //event.pageX = DOMAssistant.def(e.pageX)? e.pageX : (event.clientX + (de.scrollLeft || b.scrollLeft) - (de.clientLeft || 0));\r
103                         //event.pageY = DOMAssistant.def(e.pageY)? e.pageY : (event.clientY + (de.scrollTop || b.scrollTop) - (de.clientTop || 0));                                                     \r
104                 };\r
105                 \r
106 \r
107                 \r
108                 if( X.UA.IE && 5 <= X.UA.IE ){\r
109                         this.offsetX       = e.offsetX; // イベントターゲット左上からの座標\r
110                         this.offsetY       = e.offsetY;                 \r
111                 }// else\r
112                 //if( e.srcElement ){\r
113                 //      this.offsetX       = e.x - e.srcElement.offsetLeft; // e.x はイベント発生要素の親要素を基準にした座標。\r
114                 //      this.offsetY       = e.y - e.srcElement.offsetTop;      \r
115                 //};\r
116                 \r
117                 this.keyCode       = e.keyCode;\r
118                 this.altKey        = e.altKey;\r
119                 this.ctrlKey       = e.ctrlKey;\r
120                 this.shiftKey      = e.shiftKey;\r
121                 \r
122                 // http://www.programming-magic.com/20090127231544/\r
123                 switch( this.type ){\r
124                         case 'click'    :\r
125                         case 'dblclick' :\r
126                                 this.which = 1;\r
127                                 break;\r
128                         case 'contextmenu' :\r
129                                 this.which = 3;\r
130                                 break;\r
131                         default :\r
132                                 btn = e.button;\r
133                                 this.which =\r
134                                         btn & 1 ? 1 :\r
135                                         btn & 4 ? 2 :\r
136                                         btn & 2 ? 3 : 0; // 左:1(click:0), 中:4, 右:2\r
137                 };\r
138                 this.wheelDeltaX = this.wheelDeltaY = e.wheelDelta / 12;\r
139         };\r
140 };\r
141 \r
142 X.Dom.Event.DOM_PRE_INIT        = ++X.Event._LAST_EVENT;\r
143 X.Dom.Event.DOM_BUILDER_COMPLETE= ++X.Event._LAST_EVENT;\r
144 X.Dom.Event.DOM_INIT            = ++X.Event._LAST_EVENT;\r
145 X.Dom.Event.XDOM_READY          = ++X.Event._LAST_EVENT;\r
146 X.Dom.Event.VIEW_ACTIVATE       = ++X.Event._LAST_EVENT;\r
147 X.Dom.Event.VIEW_DEACTIVATE     = ++X.Event._LAST_EVENT;\r
148 X.Dom.Event.VIEW_RESIZED        = ++X.Event._LAST_EVENT;\r
149 X.Dom.Event.BASE_FONT_RESIZED   = ++X.Event._LAST_EVENT;\r
150 // same_page_jump\r
151 // on_screen_keyboard_show\r
152 // on_screen_keyboard_hide\r
153 X.Dom.Event.BEFORE_UPDATE       = ++X.Event._LAST_EVENT;\r
154 X.Dom.Event.AFTER_UPDATE        = ++X.Event._LAST_EVENT;\r
155 // hash_change\r
156 X.Dom.Event.BEFORE_UNLOAD       = ++X.Event._LAST_EVENT;\r
157 X.Dom.Event.UNLOAD              = ++X.Event._LAST_EVENT;\r
158 X.Dom.Event.LOAD_BEFORE_STOP    = ++X.Event._LAST_EVENT;\r
159 X.Dom.Event.LOAD_ASSET_STOP     = ++X.Event._LAST_EVENT;\r
160 X.Dom.Event.LOAD_ASSET_COMPLETE = ++X.Event._LAST_EVENT;\r
161 X.Dom.Event.LOAD_ASSET_ERROR    = ++X.Event._LAST_EVENT;\r
162 \r
163 X.Dom.Event.ANIME_BEFORE_START  = ++X.Event._LAST_EVENT;\r
164 X.Dom.Event.ANIME_START         = ++X.Event._LAST_EVENT;\r
165 X.Dom.Event.ANIME               = ++X.Event._LAST_EVENT;\r
166 X.Dom.Event.ANIME_END           = ++X.Event._LAST_EVENT;\r
167 X.Dom.Event.ANIME_BEFORE_STOP   = ++X.Event._LAST_EVENT; // xnode.stop() のみ、指定時間による停止では呼ばれない\r
168 X.Dom.Event.ANIME_STOP          = ++X.Event._LAST_EVENT;\r
169 X.Dom.Event._LAST_EVENT         = X.Event._LAST_EVENT; // ここに書いてあるイベントの最後の値 X.Dom.Event.ANIME_STOP と同じ値\r
170 \r
171 X.Dom.Event.Rename = {};\r
172 X.Dom.Event.RenameTo = {};\r
173 // https://github.com/georgeadamson/jQuery.prefixfree-events/blob/master/jQuery.prefixfree-events.js\r
174 \r
175 if( window.onwebkitanimationend !== undefined && window.onanimationend === undefined ){\r
176         X.Dom.Event.Rename[ 'animationend' ]               = 'webkitAnimationEnd';\r
177         X.Dom.Event.RenameTo[ 'webkitAnimationEnd' ]       = 'animationend';\r
178         X.Dom.Event.Rename[ 'animationstart' ]             = 'webkitAnimationStart';\r
179         X.Dom.Event.RenameTo[ 'webkitAnimationStart' ]     = 'animationstart';\r
180         X.Dom.Event.Rename[ 'animationiteration' ]         = 'webkitAnimationIteration';\r
181         X.Dom.Event.RenameTo[ 'webkitAnimationIteration' ] = 'animationiteration';\r
182 };\r
183 \r
184 if( window.onwebkittransitionend !== undefined && window.ontransitionend === undefined ){\r
185         X.Dom.Event.Rename[ 'transitionend' ]         = 'webkitTransitionEnd';\r
186         X.Dom.Event.RenameTo[ 'webkitTransitionEnd' ] = 'transitionend';\r
187 };\r
188 \r
189 X.Dom.Node.prototype.listen = function( type, arg1, arg2, arg3 /* [ listener || ( context + function ) || function ][ arguments ] */ ){\r
190         var elm;\r
191         \r
192         if( this._xnodeType === 0 || this._xnodeType === 3 || !arg1 ) return this;\r
193         \r
194         ( !this._listeners || !this._listeners[ type ] ) && this._addEvent( type );\r
195         \r
196         return typeof arg1 === 'function' ?\r
197                 X.EventDispatcher.prototype.listen.call( this, type, this, arg1, arg2 ) :\r
198                 X.EventDispatcher.prototype.listen.apply( this, arguments );\r
199 };\r
200 \r
201 X.Dom.Node.prototype._addEvent =\r
202         X.Dom.EVENT_W3C ?\r
203                 (function( type ){\r
204                         this._rawNode && this._rawNode.addEventListener( X.Dom.Event.Rename[ type ] || type, this, false );\r
205                 }) :\r
206         X.Dom.EVENT_IE ?\r
207                 (function( type ){\r
208                         if( !this._rawNode ) return;\r
209                         this._handleEvent = this._handleEvent || X.Callback.create( this );\r
210                         this._rawNode.attachEvent( 'on' + type, this._handleEvent );\r
211                 }) :\r
212                 (function( type ){\r
213                         var elm = this._ie4getRawNode();\r
214                         if( !elm ) return;\r
215                         this._handleEvent = elm[ 'on' + type ] = this._handleEvent || X.Callback.create( this );\r
216                 });\r
217 \r
218 \r
219 X.Dom.Node.prototype.unlisten = function( type /* , arg1, arg2, arg3 */ ){\r
220         var list = this._listeners,\r
221                 l    = !this._dispatching && list && type !== undefined && list[ type ] && list[ type ].length;\r
222         \r
223         X.EventDispatcher.prototype.unlisten.apply( this, arguments );\r
224         \r
225         l && !list[ type ] && this._removeEvent( type );\r
226         \r
227         return this;\r
228 };\r
229 \r
230 X.Dom.Node.prototype._removeEvent =\r
231         X.Dom.EVENT_W3C ?\r
232                 (function( type ){\r
233                         var elm = this._rawNode;\r
234                         if( !elm ) return;\r
235                         elm.removeEventListener( X.Dom.Event.Rename[ type ] || type, this, false );\r
236                 }) :\r
237         X.Dom.EVENT_IE ?\r
238                 (function( type ){\r
239                         var elm = this._rawNode;\r
240                         if( !elm ) return;\r
241                         elm.detachEvent( 'on' + type, this._handleEvent );\r
242                         if( !this._listeners ){\r
243                                 X.Callback._correct( this._handleEvent );\r
244                                 delete this._handleEvent;\r
245                         };\r
246                 }) :\r
247                 (function( type ){\r
248                         var elm = this._rawNode || this._ie4getRawNode();\r
249                         if( !elm ) return;\r
250                         elm[ 'on' + type ] = X.emptyFunction;\r
251                         elm[ 'on' + type ] = '';\r
252                         if( !this._listeners ){\r
253                                 X.Callback._correct( this._handleEvent );\r
254                                 delete this._handleEvent;\r
255                         };\r
256                 });\r
257 \r
258 \r
259 X.Dom.Node.prototype.handleEvent =\r
260         X.Dom.EVENT_W3C ?\r
261                 (function( e ){\r
262                         var ret = X.EventDispatcher.prototype.dispatch.call( this, new X.Dom.Event( e, this ) );\r
263 \r
264                         if( ret & X.Callback.STOP_PROPAGATION ){\r
265                                 e.stopPropagation();\r
266                         };\r
267                         if( ret & X.Callback.PREVENT_DEFAULT ){\r
268                                 this._tag === 'A' && this._rawNode.blur();\r
269                                 e.preventDefault();\r
270                                 return false;\r
271                         };\r
272                 }) :\r
273                 (function(){\r
274                         var ret = X.EventDispatcher.prototype.dispatch.call( this, new X.Dom.Event( event, this, this._rawNode ) );\r
275 \r
276                         if( ret & X.Callback.STOP_PROPAGATION ){\r
277                                 event.cancelBubble = true;\r
278                         };\r
279                         if( ret & X.Callback.PREVENT_DEFAULT ){\r
280                                 this._tag === 'A' && this._rawNode.blur();\r
281                                 return event.returnValue = false;\r
282                         };\r
283                 });\r
284 \r
285 \r
286 // イベントの退避、dom が画面から抜かれる場合に実施しておく\r
287 X.Dom.Node.prototype._migrateEvent = function(){\r
288         var hash = this._listeners,\r
289                 type;\r
290         if( !hash ) return;\r
291         for( type in hash ){\r
292                 this._removeEvent( type );\r
293         };\r
294 };\r
295 \r
296 // 退避したイベントの復帰\r
297 X.Dom.Node.prototype._restoreEvent = function(){\r
298         var hash = this._listeners,\r
299                 type;\r
300         if( !hash ) return;\r
301         for( type in hash ){\r
302                 this._addEvent( type );\r
303         };\r
304 };\r
305 \r
306 \r
307 \r
308 /* -----------------------------------------------\r
309  * Document Ready\r
310  *  Dean Edwards/Matthias Miller/John Resig\r
311  */\r
312 /* for ie9+/Mozilla/Opera9 */\r
313 if( X.Dom.DOM_W3C ){\r
314         X.Dom.Node._document.listenOnce( 'DOMContentLoaded', X.Dom._init );\r
315 } else\r
316 if( 5 <= X.UA.IE && X.inHead ){\r
317         // if this script in Head\r
318         document.write( "<script id=__ie_onload defer src=javascript:void(0)><\/script>" );\r
319         X.Dom._script = document.getElementById( "__ie_onload" );\r
320         X.Dom._script.onreadystatechange = function(){\r
321                 this.readyState === 'complete' && X.Dom._init();\r
322         };\r
323 } else\r
324 if( X.UA.WebKit ){ // sniff\r
325         X.Timer.add( 10, function(){\r
326                 if( !X.Dom._init ) return X.Callback.UN_LISTEN;\r
327                 if( 'loaded|complete'.indexOf( document.readyState ) !== -1 ) return X.Dom._init();\r
328         });\r
329 };\r
330 \r
331 /* for other browsers */\r
332 X.Dom.Node._window.listenOnce( 'load', X.Dom._init );\r
333 \r
334 //\r
335 X.Dom.listenOnce( X.Dom.Event.XDOM_READY, function(e){ console.log( 'X.Dom XDomReady ' + X.Dom.readyState ); } );\r
336 \r
337 X.Dom.listenOnce( X.Dom.Event.VIEW_RESIZED, function(e){ console.log( 'X.Dom VIEW_RESIZED ' + e.w + 'x' + e.h ); } );\r
338 \r