Wednesday, January 22, 2014

Preserving Chained Calls Using wrap()

Chained function calls are a staple of jQuery coding style. Rather than make one call, store the resulting jQuery object in a new variable, make another call, etc., we can chain the operations together. It doesn't even have to be the same element. For example, using end(), you can reach deep down into the DOM hierarchy, make a change, then continue along. All in the same call chain. So how does wrap() help us with call chains?

Consider the following code.
$.each( links, function( i, link ) {
    var $a = $( "<a/>" ).attr( "title", link.name )
                        .attr( "href", link.href )
                        .text( link.name );
    $( "<li/>" ).append( $a ).appendTo( $ul );
});
While there's nothing wrong with it, it does need to break the call chain in order to append the <a/> element to the <li/> element. It does this by building the <a/>, placing it in the $a variable, then appending that to the <li/>. Here's where the wrap() function comes in handy.
$.each( links, function( i, link ) {
    $( "<a/>" ).attr( "title", link.name )
               .attr( "href", link.href )
               .text( link.name )
               .appendTo( $ul )
               .wrap( "<li/>" );
});
Here, we don't even need an $a variable to hold the element while we're building the <li/>. Instead, we append the <a/> to the <ul/>. Wait, what? Yes, appending the <a/> to the <ul/> let's us use wrap(), without breaking the chain. And there's no need to setup a temporary variable using this approach.