@@ -28,7 +28,8 @@ var props = {
2828 "transition" : { }
2929 } ,
3030 testElement = document . createElement ( "a" ) ,
31- vendorPrefixes = [ "" , "webkit-" , "moz-" , "o-" ] ;
31+ vendorPrefixes = [ "" , "webkit-" , "moz-" , "o-" ] ,
32+ callbackLookupTable = { } ;
3233
3334$ . each ( [ "animation" , "transition" ] , function ( i , test ) {
3435
@@ -62,70 +63,86 @@ $.support.cssAnimations = ( props[ "animation" ][ "prefix" ] !== undefined );
6263$ ( testElement ) . remove ( ) ;
6364
6465// Animation complete callback
65- $ . fn . animationComplete = function ( callback , type , fallbackTime ) {
66- var timer , duration ,
67- that = this ,
68- eventBinding = function ( ) {
69-
70- // Clear the timer so we don't call callback twice
71- clearTimeout ( timer ) ;
72- callback . apply ( this , arguments ) ;
73- } ,
74- animationType = ( ! type || type === "animation" ) ? "animation" : "transition" ;
75-
76- if ( ! this . length ) {
77- return this ;
78- }
66+ $ . fn . extend ( {
67+ animationComplete : function ( callback , type , fallbackTime ) {
68+ var timer , duration ,
69+ that = this ,
70+ eventBinding = function ( ) {
71+
72+ // Clear the timer so we don't call callback twice
73+ clearTimeout ( timer ) ;
74+ callback . apply ( this , arguments ) ;
75+ } ,
76+ animationType = ( ! type || type === "animation" ) ? "animation" : "transition" ;
77+
78+ if ( ! this . length ) {
79+ return this ;
80+ }
7981
80- // Make sure selected type is supported by browser
81- if ( ( $ . support . cssTransitions && animationType === "transition" ) ||
82- ( $ . support . cssAnimations && animationType === "animation" ) ) {
82+ // Make sure selected type is supported by browser
83+ if ( ( $ . support . cssTransitions && animationType === "transition" ) ||
84+ ( $ . support . cssAnimations && animationType === "animation" ) ) {
8385
84- // If a fallback time was not passed set one
85- if ( fallbackTime === undefined ) {
86+ // If a fallback time was not passed set one
87+ if ( fallbackTime === undefined ) {
8688
87- // Make sure the was not bound to document before checking .css
88- if ( this . context !== document ) {
89+ // Make sure the was not bound to document before checking .css
90+ if ( this . context !== document ) {
8991
90- // Parse the durration since its in second multiple by 1000 for milliseconds
91- // Multiply by 3 to make sure we give the animation plenty of time.
92- duration = parseFloat (
93- this . css ( props [ animationType ] . duration )
94- ) * 3000 ;
95- }
92+ // Parse the durration since its in second multiple by 1000 for milliseconds
93+ // Multiply by 3 to make sure we give the animation plenty of time.
94+ duration = parseFloat (
95+ this . css ( props [ animationType ] . duration )
96+ ) * 3000 ;
97+ }
9698
97- // If we could not read a duration use the default
98- if ( duration === 0 || duration === undefined || isNaN ( duration ) ) {
99- duration = $ . fn . animationComplete . defaultDuration ;
99+ // If we could not read a duration use the default
100+ if ( duration === 0 || duration === undefined || isNaN ( duration ) ) {
101+ duration = $ . fn . animationComplete . defaultDuration ;
102+ }
100103 }
101- }
102104
103- // Sets up the fallback if event never comes
104- timer = setTimeout ( function ( ) {
105- that
106- . off ( props [ animationType ] . event , eventBinding )
107- . each ( function ( ) {
105+ // Sets up the fallback if event never comes
106+ timer = setTimeout ( function ( ) {
107+ that
108+ . off ( props [ animationType ] . event , eventBinding )
109+ . each ( function ( ) {
110+ callback . apply ( this ) ;
111+ } ) ;
112+ } , duration ) ;
113+
114+ // Update lookupTable
115+ callbackLookupTable [ callback ] = {
116+ event : props [ animationType ] . event ,
117+ binding : eventBinding
118+ } ;
119+
120+
121+ // Bind the event
122+ return this . one ( props [ animationType ] . event , eventBinding ) ;
123+ } else {
124+
125+ // CSS animation / transitions not supported
126+ // Defer execution for consistency between webkit/non webkit
127+ setTimeout ( function ( ) {
128+ that . each ( function ( ) {
108129 callback . apply ( this ) ;
109130 } ) ;
110- } , duration ) ;
131+ } , 0 ) ;
132+ return this ;
133+ }
134+ } ,
111135
112- // Bind the event
113- return this . one ( props [ animationType ] . event , eventBinding ) ;
114- } else {
136+ removeAnimationComplete : function ( callback ) {
137+ var callbackInfoObject = callbackLookupTable [ callback ] ;
115138
116- // CSS animation / transitions not supported
117- // Defer execution for consistency between webkit/non webkit
118- setTimeout ( function ( ) {
119- that . each ( function ( ) {
120- callback . apply ( this ) ;
121- } ) ;
122- } , 0 ) ;
123- return this ;
139+ return callbackInfoObject ?
140+ this . off ( callbackInfoObject . event , callbackInfoObject . binding ) : this ;
124141 }
125- } ;
142+ } ) ;
126143
127144// Allow default callback to be configured on mobileInit
128145$ . fn . animationComplete . defaultDuration = 1000 ;
129146
130- return $ . fn . animationComplete ;
147+ return $ ;
131148} ) ;
0 commit comments