{"id":150360,"date":"2013-09-19T08:47:57","date_gmt":"2013-09-19T15:47:57","guid":{"rendered":"http:\/\/css-tricks.com\/?page_id=150360"},"modified":"2015-10-27T07:57:11","modified_gmt":"2015-10-27T14:57:11","slug":"12-callback-functions","status":"publish","type":"page","link":"https:\/\/css-tricks.com\/lodge\/learn-jquery\/12-callback-functions\/","title":{"rendered":"#12: Callback Functions"},"content":{"rendered":"

Everybody’s favorite: concept video time! Callbacks are an important concept in JavaScript. They are functions that are called when an action has completed running. Then lend structure and timing to our code. <\/p>\n

Take for example the animation we used in the last video. Animations take time to run. What if you want to have something else happen right when that animation finishes? Do you have to do a setTimeout<\/code> for the same length as the animation? Nope. jQuery gives us callback functions used just for that purpose.<\/p>\n

They are typically an additional parameter that we pass to the method. In the case of animation, we pass a function as the last parameter. That is the callback function, and will be called when the animation is complete. <\/p>\n

$(\"#element\").animate({\r\n  \/\/ stuff to animate\r\n}, function() {\r\n  \/\/ callback function\r\n});<\/code><\/pre>\n

That looks a little funky perhaps, but essentially we’re just doing:<\/p>\n

.animate(a, b)<\/code><\/pre>\n

Where a<\/code> is an object of properties and values, and b<\/code> is a callback function. <\/p>\n

But we know from the last video that animation can also take a timing parameter that specifies how long an animation will take. Where does that go? That’s an optional<\/em> parameter, just like the callback function is. If we wanted to use it, we’d put it right in the middle, so essentially:<\/p>\n

.animate(propertiesObject, duration, callback);<\/code><\/pre>\n

And there is another optional parameter too, a string we can pass to specify an easing value. <\/p>\n

.animate(propertiesObject, duration, easing, callback);<\/code><\/pre>\n

jQuery just happens to be cool and smart about those optional parameters. If you leave out the middle two and just pass the callback, it can tell what you are passing is a function, not a number or string, so it knows you mean a callback function. You don’t have to pass in bogus values or anything. That’s just good API design!<\/p>\n

When you look at the jQuery documentation<\/a>, they show it like this:<\/p>\n

.animate( properties [, duration ] [, easing ] [, complete ] )<\/p><\/blockquote>\n

Then right after explain the expected types.<\/p>\n

But anyway, back to callbacks. You can get pretty nested. Imagine putting another animation in the callback function, and that animation has its own callback. That’s perfectly reasonable, as you might want to do a multi-step animation. You just need to stay organized.<\/p>\n

See the Pen 450c5810be27a9a8946cb8012cbd1213<\/a> by Chris Coyier (@chriscoyier<\/a>) on CodePen<\/a><\/p>\n

We’re just using animation as an example here. Perhaps an even more common use of callback functions is Ajax. Ajax is when the browser calls out for another resource without refreshing the page. That can take a completely unknown amount of time. It depends on bandwidth and latency and the size of the file and error conditions and all kinds of stuff. You likely can’t do anything with that Ajax request until you get something back or otherwise more information. Callback functions are perfect for that, and we’ll get into that later on. <\/p>\n","protected":false},"excerpt":{"rendered":"

Everybody’s favorite: concept video time! Callbacks are an important concept in JavaScript. They are functions that are called when an action has completed running. Then lend structure and timing to our code. Take for example the animation we used in the last video. Animations take time to run. What if you want to have something […]<\/p>\n","protected":false},"author":3,"featured_media":0,"parent":147848,"menu_order":0,"comment_status":"open","ping_status":"closed","template":"lodge-video.php","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"sig_custom_text":"","sig_image_type":"featured-image","sig_custom_image":0,"sig_is_disabled":false,"inline_featured_image":false,"c2c_always_allow_admin_comments":false,"footnotes":""},"tags":[],"acf":[],"jetpack-related-posts":[{"id":15342,"url":"https:\/\/css-tricks.com\/snippets\/jquery\/animate-heightwidth-to-auto\/","url_meta":{"origin":150360,"position":0},"title":"Animate Height\/Width to “Auto”","date":"November 30, 2011","format":false,"excerpt":"It's not possible to do thing.animate({ \"height\": \"auto\" });. So this is Darcy Clarke's method to allow that to work. You essentially clone the element, remove the fixed heights currently inflicting the element, and measure\/save the value. Then you animate the real element to that value. jQuery.fn.animateAuto = function(prop, speed,\u2026","rel":"","context":"With 27 comments","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":5018,"url":"https:\/\/css-tricks.com\/snippets\/wordpress\/customize-comments-markup\/","url_meta":{"origin":150360,"position":1},"title":"Customize Comments Markup","date":"December 12, 2009","format":false,"excerpt":"In a typical WordPress theme you output the entire list of comments for a Post\/Page by using the function wp_list_comments(). This doesn't offer much by the way of customizing what HTML markup gets generated for that comment list. To write your own markup for the comment list, you can use\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":5953,"url":"https:\/\/css-tricks.com\/snippets\/jquery\/combine-slide-and-fade-functions\/","url_meta":{"origin":150360,"position":2},"title":"Combine Slide and Fade Functions","date":"March 16, 2010","format":false,"excerpt":"$.fn.slideFadeToggle = function(speed, easing, callback) { return this.animate({opacity: 'toggle', height: 'toggle'}, speed, easing, callback); }; Usage $(\"#something\").click(function() { $(this).slideFadeToggle(); });","rel":"","context":"In "Article"","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":249342,"url":"https:\/\/css-tricks.com\/snippets\/javascript\/replacements-setinterval-using-requestanimationframe\/","url_meta":{"origin":150360,"position":3},"title":"Replacements for setInterval Using requestAnimationFrame","date":"December 26, 2016","format":false,"excerpt":"When it comes to animation, we're told that setInterval is a bad idea. Because, for example, the loop will run regardless of anything else going on, rather than politely yielding like requestAnimationFrame will. Also some browsers might \"play catchup\" with a setInterval loop, where an inactive tab might have been\u2026","rel":"","context":"With 1 comment","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":15825,"url":"https:\/\/css-tricks.com\/snippets\/javascript\/async-script-loader-with-callback\/","url_meta":{"origin":150360,"position":4},"title":"Async Script Loader with Callback","date":"January 3, 2012","format":false,"excerpt":"var Loader = function () { } Loader.prototype = { require: function (scripts, callback) { this.loadCount = 0; this.totalRequired = scripts.length; this.callback = callback; for (var i = 0; i < scripts.length; i++) { this.writeScript(scripts[i]); } }, loaded: function (evt) { this.loadCount++; if (this.loadCount == this.totalRequired && typeof this.callback ==\u2026","rel":"","context":"With 15 comments","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":155729,"url":"https:\/\/css-tricks.com\/lodge\/learn-jquery\/28-building-complex-plugin\/","url_meta":{"origin":150360,"position":5},"title":"#28: Building a More Complex Plugin","date":"November 11, 2013","format":false,"excerpt":"Now that we understand the basics of plugin development, we can dig a little deeper. Because ultimately a plugin is a function, it provides us the scope we need to organize. Remember when we got our house in order when we were learning about templating? We can use some of\u2026","rel":"","context":"With 3 comments","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/pages\/150360"}],"collection":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/comments?post=150360"}],"version-history":[{"count":3,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/pages\/150360\/revisions"}],"predecessor-version":[{"id":150590,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/pages\/150360\/revisions\/150590"}],"up":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/pages\/147848"}],"wp:attachment":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/media?parent=150360"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/tags?post=150360"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}