clearTimeout = window.clearTimeout,\r
INTERVAL_TIME = 16,\r
TICKET_LIST = [],\r
- timerId = -1,\r
+ uid = 0,\r
+ timerId = 0,\r
+ endTime = 0,\r
next = 0,\r
INDEX_TIME = 0,\r
INDEX_LAST = 1,\r
INDEX_COUNT = 2,\r
- INDEX_CALLBACK = 3;\r
+ INDEX_CALLBACK = 3,\r
+ INDEX_UID = 4;\r
\r
function loop(){\r
var c = next,\r
f = queue[ INDEX_CALLBACK ];\r
c = queue[ INDEX_COUNT ];\r
ret = f();\r
- if( ret === false || ret & X.Callback.UN_LISTEN || c === 1 ){\r
+ if( ret & X.Callback.UN_LISTEN || c === 1 ){\r
list.splice( i, 1 );\r
- f.kill();\r
+ f.kill && f.kill();\r
queue.length = 0;\r
continue;\r
} else\r
if( 1 < c ) --queue[ INDEX_COUNT ];\r
queue[ INDEX_LAST ] = queue[ INDEX_TIME ];\r
};\r
- timerId = -1;\r
+ timerId = 0;\r
update();\r
};\r
function update(){\r
last;\r
if( l === 0 ){\r
timerId !== -1 && clearTimeout( timerId );\r
- timerId = -1;\r
+ timerId = 0;\r
return;\r
};\r
for( ; l; ){\r
( last = list[ --l ][ INDEX_LAST ] ) < n && ( n = last );\r
};\r
- if( n < next || timerId === -1 ){\r
- timerId !== -1 && clearTimeout( timerId );\r
- timerId = setTimeout( loop, INTERVAL_TIME * n );\r
+ if( n < next || timerId === 0 ){\r
+ timerId !== 0 && clearTimeout( timerId );\r
+ timerId = setTimeout( loop, INTERVAL_TIME * n );\r
+ endTime = X.getTime() + INTERVAL_TIME * n;\r
next = n;\r
};\r
};\r
\r
+ // http://havelog.ayumusato.com/develop/javascript/e528-ios6_scrolling_timer_notcall.html\r
+ // iOS6 スクロール中のタイマー発火絡みのバグ備忘\r
+ if( X.UA.iOS ){\r
+ window.addEventListener( 'scroll', function(){\r
+ if( timerId ){\r
+ clearTimeout( timerId );\r
+ timerId = setTimeout( loop, Math.max( 0, endTime - X.getTime() ) );\r
+ };\r
+ } );\r
+ };\r
+ \r
+ var enterFrame =\r
+ window.requestAnimationFrame ||\r
+ window.webkitRequestAnimationFrame ||\r
+ window.mozRequestAnimationFrame ||\r
+ window.oRequestAnimationFrame ||\r
+ window.msRequestAnimationFrame ||\r
+ 0,\r
+ cancelFrame =\r
+ window.cancelRequestAnimationFrame ||\r
+ window.webkitCancelAnimationFrame ||\r
+ window.webkitCancelRequestAnimationFrame ||\r
+ window.mozCancelRequestAnimationFrame ||\r
+ window.oCancelRequestAnimationFrame ||\r
+ window.msCancelRequestAnimationFrame ||\r
+ 0,\r
+ REQUEST_FRAME_LIST = [],\r
+ requestID;\r
+ \r
+ function onEnterFrame( time ){\r
+ var list = REQUEST_FRAME_LIST,\r
+ i = list.length,\r
+ f;\r
+ time = time || ( Date.now ? Date.now() : +new Date );\r
+ for( ; i; ){\r
+ ( f = list[ --i ] )( time );\r
+ delete f.uid;\r
+ f.kill && f.kill();\r
+ };\r
+ list.length = 0;\r
+ };\r
+ \r
return {\r
add : function( time, opt_count, args1, args2, args3 ){\r
time = time < INTERVAL_TIME ? 1 : ( time / INTERVAL_TIME ) | 0; // 正の数で使える「Math.floor(x)」を「(x | 0)」に;\r
opt_count = 0;\r
};\r
\r
- TICKET_LIST[ TICKET_LIST.length ] = [ time, time, opt_count, X.Callback.create( args1, args2, args3 ) ];\r
+ TICKET_LIST[ TICKET_LIST.length ] = [ time, time, opt_count, X.Callback.create( args1, args2, args3 ), ++uid ];\r
update();\r
+ return uid;\r
},\r
once : function( time, args1, args2, args3 ){\r
- X.Timer.add( time, 1, args1, args2, args3 );\r
+ return X.Timer.add( time, 1, args1, args2, args3 );\r
},\r
- remove : function( args1, args2 ){\r
- var queue,\r
- i = 0,\r
- list = TICKET_LIST;\r
- if( !callback ) return;\r
- while( queue = list[ i ] ){\r
- if( queue[ INDEX_CALLBACK ].same( args1, args2 ) === true ){\r
- callback.kill();\r
+ remove : function( uid ){\r
+ var list = TICKET_LIST,\r
+ i = list.length,\r
+ l = i,\r
+ f, q;\r
+ for( ; i; ){\r
+ if( ( q = list[ --i ] )[ INDEX_UID ] === uid ){\r
list.splice( i, 1 );\r
+ f = q[ INDEX_CALLBACK ];\r
+ f.kill && f.kill();\r
+ ( /* q[ INDEX_COUNT ] <= next || */ l === 1 ) && update();\r
+ q.length = 0;\r
break;\r
- } else {\r
- ++i;\r
};\r
};\r
- update();\r
- }\r
+ },\r
\r
// string only ie4-\r
- ,_loop : X.UA.IE && X.UA.IE < 5 && (function(){\r
- var _loop = loop;\r
+ _loop : X.UA.IE && X.UA.IE < 5 && (function( r ){\r
loop = 'X.Timer._loop()';\r
- return _loop;\r
- })()\r
+ return r;\r
+ })( loop ),\r
\r
+ requestFrame : function( args1, args2, args3 ){\r
+ var i = REQUEST_FRAME_LIST.length,\r
+ f;\r
+ i === 0 && ( requestID = ( enterFrame ? enterFrame( onEnterFrame ) : X.Timer.add( 0, 1, onEnterFrame ) ) );\r
+ f = REQUEST_FRAME_LIST[ i ] = X.Callback.create( args1, args2, args3 );\r
+ return f.uid = ++uid;\r
+ },\r
+ cancelFrame : function( uid ){\r
+ var list = REQUEST_FRAME_LIST,\r
+ l = list.length,\r
+ i = l,\r
+ f;\r
+ for( ; i; ){\r
+ if( ( f = list[ --i ] ).uid < uid ) break;\r
+ if( f.uid === uid ){\r
+ list.splice( i, 1 );\r
+ delete f.uid;\r
+ f.kill && f.kill();\r
+ l === 1 && ( cancelFrame ? cancelFrame( requestID ) : X.Timer.remove( requestID ) );\r
+ break;\r
+ };\r
+ };\r
+ }\r
};\r
})();
\ No newline at end of file