X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;ds=sidebyside;f=0.6.x%2Fjs%2F01_core%2F13_XEventDispatcher.js;h=25c2d11477034a160a6fcb231065e418636740b8;hb=7d3b5c3962eea3585a009bfc290a71560b2e83b3;hp=1aaadc5f0101210e0034c1a9058202406cc9eb54;hpb=57e35f063b4a70fcec59db6ec7366b43f41f0ba4;p=pettanr%2FclientJs.git diff --git a/0.6.x/js/01_core/13_XEventDispatcher.js b/0.6.x/js/01_core/13_XEventDispatcher.js index 1aaadc5..25c2d11 100644 --- a/0.6.x/js/01_core/13_XEventDispatcher.js +++ b/0.6.x/js/01_core/13_XEventDispatcher.js @@ -74,9 +74,9 @@ X.EventDispatcher = /** * _rawObject には HTMLElement, window, document, XHR といったイベントターゲットオブジェクトを設定します。 - * _rawObject が設定されていると on(), off() 時に addEventListener(DOM Level2) や detachEvent(ie5~8), on~(DOM0) 等を操作します。 - * _rawObject は最初の on() 前に設定しておかないと addEventListener 等が意図したように行われません。 - * X.Node では非同期に HTMLElement を生成していて、要素生成以前に on, off を呼び出すことができます。これは適宜に migrateEvent, restoreEvent を呼んで解決しているためです。 + * _rawObject が設定されていると listen(), unlisten() 時に addEventListener(DOM Level2) や detachEvent(ie5~8), on~(DOM0) 等を操作します。 + * _rawObject は最初の listen() 前に設定しておかないと addEventListener 等が意図したように行われません。 + * X.Node では非同期に HTMLElement を生成していて、要素生成以前に listen, unlisten を呼び出すことができます。これは適宜に X_EventDispatcher_toggleAllEvents を呼んで解決しているためです。 * @private * @type {Object} */ @@ -120,6 +120,14 @@ X.EventDispatcher = * @type {boolean} */ '_killReserved' : false, + + /** + * asyncDispatch 中に kill が呼ばれた場合に、X.EventDispatcher インスタンスの削除を最後のタイマーの発火後にずらすために立てるフラグ。 + * TODO asyncDispatch の解除はどうする? + * @private + * @type {boolean} + */ + '_lastLazyID' : false, /** * X.EventDispatcher のコンストラクタの実体。 @@ -140,11 +148,6 @@ X.EventDispatcher = * @param {(eventHash|string|number)} e */ dispatch : X_EventDispatcher_dispatch, - - /** - * @function - */ - on : X_EventDispatcher_listen, /** * @@ -172,8 +175,7 @@ X.EventDispatcher = X_EventDispatcher_once = false; return this; }, - - off : X_EventDispatcher_unlisten, + unlisten : X_EventDispatcher_unlisten, /** @@ -235,7 +237,7 @@ X.EventDispatcher = e = delay; delay = 0; }; - return X.Timer.add( delay, 1, this, this.dispatch, [ e ] ); + return this[ '_lastLazyID' ] = X.Timer.add( delay, 1, this, X_EventDispatcher_dispatch, [ e ] ); } } ); @@ -303,6 +305,11 @@ function X_EventDispatcher_dispatch( e ){ }; if( ( --this._dispatching ) === 0 ){ + + if( this[ '_lastLazyID' ] && X_Timer_currentUID === this[ '_lastLazyID' ] ){ + delete this[ '_lastLazyID' ]; + }; + // dispatch 中に unlisten された要素の削除 unlistens = this._unlistens; delete this._dispatching; @@ -310,6 +317,7 @@ function X_EventDispatcher_dispatch( e ){ // _unlistens に入っている callbackHash は、lock をクリアしている X_EventDispatcher_unlock = true; for( type in unlistens ){ + //if( X_EMPTY_OBJECT[ type ] ) continue; list = unlistens[ type ]; for( i = list.length; i; ){ this.unlisten( type, list[ --i ] ); @@ -425,6 +433,7 @@ function X_EventDispatcher_unlisten( opt_type, opt_arg1, opt_arg2, opt_arg3 ){ if( opt_type === undefined ){ // 全て削除 for( opt_type in list ){ + //if( X_EMPTY_OBJECT[ opt_type ] ) continue; _list = list[ opt_type ]; for( i = _list.length; i; ){ this.unlisten( opt_type, _list[ --i ] ); // override されていることがあるので、必ず unlisten を使用 @@ -515,13 +524,19 @@ var X_EventDispatcher_actualAddEvent = if( that._isSilverlight ){ list.slcallback = X_Callback_create( that, X_EventDispatcher_sliverLightDispatch, [ type ] ); list.sltoken = raw.AddEventListener( type, list.slcallback ); + } else + // iOS と MacOSX Iron36 で発生。連続してアニメーションが起こると、クロージャの束縛された obj へのアクセスに失敗する。Win では起きない? + // むしろ、MacOSX のブラウザ全般で起こる?? + if( ( X_UA.WebKit || X_UA.Blink ) && + ( type === 'webkitTransitionEnd' || type === 'transitionend' || + type === 'animationend' || type === 'webkitAnimationEnd' || + type === 'animationstart' || type === 'webkitAnimationStart' || + type === 'animationiteration' || type === 'webkitAnimationIteration' ) ){ + raw.addEventListener( type, X_EventDispatcher_iOSTransitionEndDispatch, false ); } else { console.log( 'event > ' + type ); that._handleEvent || ( that._handleEvent = X_Callback_create( that, X_EventDispatcher_actualHandleEvent ) ); - - if( X.UA.iOS && type === 'webkitTransitionEnd' ){ - raw.addEventListener( type, X_EventDispatcher_iOS3transitionEndDispatch, false ); - } else + if( raw.addEventListener ){ raw.addEventListener( type, that._handleEvent, false ); } else { @@ -569,8 +584,8 @@ var X_EventDispatcher_actualAddEvent = * 参照できていない問題に遭遇、、、iOS3.1.3 & iOS6.1.5 で確認 * animation も怪しい、、、 */ -function X_EventDispatcher_iOS3transitionEndDispatch( e ){ - return X_Node_getXNode( this ).dispatch( X_Event_RenameTo[ e.type ] ); +function X_EventDispatcher_iOSTransitionEndDispatch( e ){ + return X_Node_getXNode( this ).dispatch( X_Event_RenameTo[ e.type ] || e.type ); }; /* @@ -606,10 +621,15 @@ var X_EventDispatcher_actualRemoveEvent = X_Callback_correct( list.slcallback ); delete list.sltoken; delete list.slcallback; + } else + if( ( X_UA.WebKit || X_UA.Blink ) && + ( type === 'webkitTransitionEnd' || type === 'transitionend' || + type === 'animationend' || type === 'webkitAnimationEnd' || + type === 'animationstart' || type === 'webkitAnimationStart' || + type === 'animationiteration' || type === 'webkitAnimationIteration' ) ){ + raw.removeEventListener( type, X_EventDispatcher_iOSTransitionEndDispatch, false ); } else { - if( X.UA.iOS && type === 'webkitTransitionEnd' ){ - raw.removeEventListener( type, X_EventDispatcher_iOS3transitionEndDispatch, false ); - } else + if( raw.addEventListener ){ raw.removeEventListener( type, that._handleEvent, false ); } else { @@ -748,6 +768,7 @@ function X_EventDispatcher_toggleAllEvents( that, add ){ type; if( !list || !raw ) return; for( type in list ){ + //if( X_EMPTY_OBJECT[ type ] ) continue; // 数字イベントの除外 if( '' + parseFloat( type ) !== type ){ // TODO type rename はここ