JQuery_ Novice to Ninja - Earle Castledine [138]
$('#ascending').click(function() {
$('ul.sortable')
.hide()
.sorter()
.slideDown();
});
The biggest change from our original SORTER widget is that once the extend is in place, we no longer call the functions and pass in parameters; instead, we treat it like a normal jQuery action, much as we would had we packaged it into a plugin. Of course, you could take this same code and make it into a plugin! Doing it on the fly like this is just another option available to you.
$. Prefixed Functions
At the beginning of the book we praised jQuery for being a very consistent library: each time we call upon it we have a selector, an action, and perhaps a few parameters. Once you learned that basic pattern, it would be essentially all you had to remember. Then, only a few paragraphs later, we snuck in some code that didn’t use a selector at all! Since then, we’ve seen several of these kinds of actions: $.ajax, $.map, $.slice, $.trim, and more.
The $. prefixed functions don’t work on a selection; rather, they’re general utility commands that can have a place outside a jQuery command chain. For example, $.map can be used to map any arbitrary array—but it can also be used to modify a jQuery selection.
The client liked the Ajax Twitter-search component we developed in Chapter 6, but wanted a more human-readable time displayed for the tweets: for example, rather than “56 seconds ago,” he’d like it to say “about a minute ago.” This sounds like a good candidate for adding to the jQuery object, since it’s the sort of functionality you’d like to be able to use outside of a selection. Any time we need a friendly looking time period, we’d like to be able to call $.lapsed(time) and obtain a nice string.
To get underway, we’ll omit the actual logic for a second while we look at the function’s structure. The skeleton looks very similar to the plugins we created —passing the jQuery object to the wrapped function—so our code will work even if the $ alias has been redefined:
chapter_09/07_$_prefixed_functions/script.js (excerpt)
(function($) {
$.lapsed = function(time) {
var then = new Date(Date.parse(time));
var now = new Date();
var minutes = Math.round((now-then) / 60000);
var lapsed;
// Determine pretty time
…
};
})(jQuery);
Now we just need to attach our function to the jQuery object itself. Because we’re extending jQuery, you’ll have to be careful to avoid unintentionally overwriting any of the built-in function names. The code we’ll use to determine the “pretty” time is nothing more than a series of if/else structures. To keep the example simple, our helper will only go as far as “more than a minute ago”—but you’ll want to extend this to account for larger time spans:
chapter_09/07_$_prefixed_functions/script.js (excerpt)
// Determine pretty time
if (minutes == 0) {
var seconds = Math.round((now - then) / 1000);
if (seconds < 10) {
lapsed = "less than 10 seconds ago";
}
else if (seconds < 20) {
lapsed = "less than 20 seconds ago";
}
else {
lapsed = "half a minute ago";
}
}
else if (minutes == 1) {
var seconds = Math.round((now-then) / 1000);
if (seconds == 30) {
lapsed = "half a minute ago";
} else if (seconds < 60) {
lapsed = "less than a minute ago";
} else {
lapsed = "1 minute ago";
}
} else {
lapsed = "more than a minute ago";
}
return lapsed;
To use this extension in our jQuery code, we pass a timestamp to the new lapsed function, and append the result wherever we need it. Our functionality is neatly encapsulated, and ready for use on any number of future projects:
chapter_09/07_$_prefixed_functions/script.js (excerpt)
.append('' + $.lapsed(this.created_at) + ↵'
Overwriting Existing Functionality
One of the main differences between adding plugins via $.fn.myPlugin rather than $.extend({ myPlugin : … }), is that the extend mechanism augments the element you’re extending, rather than replacing it entirely. This is what makes it possible to extend jQuery itself (or existing plugins) with additional functionality. As well as adding new methods