It never ceases to amaze me at how much I don’t know.
jQuery is a pretty straight forward library. It’s essentially one large object off of which we can call and chain functions. The beauty of it is in it’s simplicity. It takes a somewhat convoluted and strange language, and makes it trivial to do really complex things. That simplicity, though, can give the illusion that you fully understand jQuery from top to bottom.
Work with the DOM and make AJAX calls right? Pfffft. I got this.
I was having lunch a while back with Elijah Manor who knows far more about jQuery (and many other things) than I do, and he mentioned the .map() function. I nodded my head and said to myself, “I have no idea what that is”. Then I said it out loud because Elijah is a really nice guy and always very helpful. But it got me to thinking – what else is there that I haven’t seen or don’t know about.
Lots Buddy. Lots.
Paul Irish did a talk about about 10 performance tips for using jQuery. Jon Raasch did a summary post that I would highly recommend reading. One of the things that he talks about at the bottom is some of the lesser known jQuery methods. And wouldn’t you know it – .map() is the first one in the list.
He doesn’t go into depth on these methods and what they do, so I’m going to pick up where he left off and write some code around these lesser known methods. Of course, please refer to the official jQuery documentation on all of these which I will link to from each one. A big thanks to Elijah who gave me input on these methods and helped with some of the ideas expressed here.
The .map() function takes in an array and operates on each item in the array, returning a new array when it is finished. Now the first thing that came to my mind is, “Why not just use .each() instead?” .each() is meant to enumerate over immutable items. For example, lets say we have a simple array of items. We want to enumerate over that array and remove an item. Conventional programming tells you not to do that. You cannot modify a collection that you are currently in the process of enumerating. If you try to do this in a static language, it will throw an error telling you the collection has changed.
The idea with .map() is that we can enumerate over the array and modify any or all elements. This returns a new array. This is the same thing that you would do if you were trying to modify a collection in a conventional foreach loop. In the following fiddle, a simple array is modified and the new array contains the new items. You can see how .map() greatly simplifies traversing and modifying an array.
For instance, in the above example we had an array of items. Suppose that array of items was an unordered list of items and we wanted to mark the third and fourth items as deleted. We could use the .slice() to do this. The first parameter is the index at which to start slicing. The second is where to end. Note that if you pass in a number less than where you started, you will get nothing. If you do not pass in a second parameter you will get the entire list starting at the index provided.
You are probably familiar with jQuery animations and simple things like .toggle() which toggles an element’s visibility with an animation. As it turns out, animations are queued, so that if you try to execute an animation on the same object while one is currently in progress, the first one finishes and then the second is executed. That’s probably not the behavior that you want. Consider this example. Suppose we add a toggle button to our list of items to show and hide it. Watch what happens when you click the “toggle” button before the animation is finished. Click the button a bunch of times and watch the animation queue, and then fire over and over again.
That's just not at all what we want. We want the current animation to cease before the next one is fired. Currently we have to wait for each animation to finish. I slowed the animation down for added effect.
Using the .stop() method, we can kill the current animation in it’s tracks and start the new one.
There are a couple of parameters that go with .stop() that are probably worth mentioning here. They are clearQueue and jumpToEnd. They are both Booleans and are passed in that order. The defaults are .stop(false,false).
clearQueue clears any animations that are in the queue. As you saw in the first toggle example, animations can get queued up and this will empty that queue.
jumpToEnd specifies that the current animation should be completed immediately. In our example using .stop(), the animation is killed in it’s tracks. This setting says that the animation will complete immediately instead of just stopping altogether.
This selects all previous same-level elements. Pretty simple and very useful. For example, in our list of items, we could attach an event handler to each item and using .prevAll() along with .map() we can return a list of the previous items.
A lot of people know about this one, but it was new to me and it is super handy. Have you ever done something like this?
What do you get back from that? Not the div jQuery object, but the input. This stinks for chaining because if you want to do several things on the div including altering some child elements, you end up doing it on a separate line. The .end() method restores the current object on the chain to it’s previous state. So in the above example, .end() would in fact give you back the div object.
I should note here that you should probably steer clear of chaining too much. It’s very useful, but can make code very difficult to maintain. If you do chain, make sure you drop down on separate lines as I did above so that it’s easier to read. In the chain indent methods that act on the same object. you can see from the structure of the code above that find() and end() are on the same level because they both refer to the div object. The text() operates on the first li, so it is indented.
Maybe not all of these functions are new to you, but it was a learning experience for me. There are quite a few functions in jQuery that get very little attention because they have a very niche use. Some of the ones that I wanted to write about, but couldn’t come up with examples for include .queue(), .dequeue(), .delay(), and .pushStack().
As you build with Kendo UI, familiarize yourself with some of the more advanced features of the jQuery library. They will come in handy when you need them and help reduce the amount of code that you have to write. It will also make you look really smart when you go to lunch with your friend and they mention .map() and you don’t look back with a blank stare like I did!