Home » Guides Advanced Article

Useful Utility Functions in mootools

Not rated
Rate:

Cory Hudson
September 15, 2006


Cory Hudson
http://www.coryhudson.com/blog
Cory Hudson has written 1 articles for JavaScriptSearch.
View all articles by Cory Hudson...

The new mootools JavaScript framework has quickly impressed me with its design and usefulness. The library was clearly written to meet real programmers’ needs while working in JavaScript. Just take a look at some of the new utility functions and methods it provides.

Note: This article covers functions and methods found in the Array.js and Function.js modules of mootools.

A cleaner array iterator

Mootools provides a Prototype-inspired each method that every JavaScript array inherits. Its syntax is a bit cleaner because it’s based on the Mozilla Array.prototype.forEach method. The mootools each method allows you to pass in a second parameter as the context in which the function will be called, allowing you to resolve the this keyword. Accomplishing this in the Prototype library involves binding the function passed to each:

var x = {sum: 0};

for (var i = 0, fixtures = []; i < 500; i++) {
fixtures.push(i);
}

fixtures.each(function(el, i) {
this.sum+= i
}.bind(x));

// x.sum = 124750

Accomplishing the same thing in mootools is just a small syntax change (the changed line is highlighted):

var x = {sum: 0};

for (var i = 0, fixtures = []; i < 500; i++) {
fixtures.push(i);
}

fixtures.each(function(el, i) {
this.sum+= i
}, x);

// x.sum = 124750

The mootools each method takes the object that will resolve to this inside the loop as the second argument.

Why should you care about this minor syntax change? Because calling bind on a function every time through a loop is going to add overhead to your code’s performance. I’ve run the previous code in Firebug with a timer and the results are very telling:

500 elements each with bind: 39ms
500 elements each: 3ms
1000 elements each with bind: 75ms
1000 elements each: 6ms

Not only is the mootools syntax cleaner, but it performs almost 10 times faster than using the bind method. Keep in mind that these examples all use mootools’ each method. If I’d used the Prototype each the code would have run even slower, but that issue has already been well-documented.

Prototype each diversion

The reason Prototype’s each loop runs so slowly is that each iteration of the loop has to run through a try/catch block in order to look for break and continue statements. If you’re using Prototype’s each and you want to break or continue in the loop, you must use the following syntax:

[1,2,3,4,5,6,7,8,9,10].each(function(el) {
if (el > 7) throw $break;
if (el == 4) throw $continue;
alert(el);
});

// Will alert "1", "2", "3", "5", "6", "7"

I’m not here to bash Prototype. It’s a great library. But I think it does need to be pointed out that its each method will run slower than traditional loops because of the design decision to incorporate a workaround for break and continue statements.

What, you’re not using break and continue statements? They can really help you cut down on loop iterations. There is no way to use break or continue in an each loop in mootools, so keep that in mind. You’ll have to use the good old-fashioned for loop for that one.

Running code at time intervals

JavaScript provides the setTimeout and setInterval functions for running code after a delay or at regular intervals. This comes in very handy for animations, but also for other GUI functions, such as delaying hiding a menu after navigating away. The native syntax for this can get a little verbose sometimes, so mootools provides some utility functions as methods of every function. To run code once after a time delay you use the delay method:

(function(){ alert("Sorry I'm late."); }).delay(5000);

This will run the function after a delay of 5 seconds. You can also run code at a regular interval using the periodical method:

var annoy = (function(){ console.log('Are we there yet?'); }).periodical(5000);

The previous code will run until the window unloads unless we clear the interval returned by periodical. Mootools provides a $clear function that will clear any time interval passed to it, whether it was created with delay or periodical:

$clear(annoy);

Just be sure to assign the periodical function to a variable, or else you won’t be able to clear it! Talk about annoying…

The second parameter to delay and periodical is the context object to call the function within, just like the each method. This can come in handy when using methods of mootools’ objects:

var xhr = new Ajax('url', {update: ajaxElement});
var $req = xhr.request.periodical(60000, xhr);

This code will create an Ajax object that calls its request object every minute. You need to pass the Ajax object as the second argument to periodical so the request method will run in the right context.

Cleaner object detection

Sometimes checking the type of a JavaScript object can get confusing. Everything is actually an Object, so running [1,2,3] instanceof Object returns true, even though we were checking against an array. But curisouly, running 'string' instanceof Object returns false! There’s also the typeof function, so things can get rather confusing and frustrating in a hurry when trying to detect object types. Mootools provides a function called $type that will do the proper checks behind the scenes and return a lowercase string type of the element you passed into the function. If the type of object is not matched, $type will return false.

The types returned by $type are:

  • function
  • textnode
  • element
  • array
  • object
  • string
  • number
  • false

Try it out:

$type(function(){});
// Returns 'function'

$type(document.createElement('div'));
// Returns 'element'

$type([]);
// Returns 'array'

$type({});
// Returns 'object'

$type('hello world');
// Returns 'string'

$type(4);
// Returns 'number'

Mootools just continues to amaze me. I’m digging through the source code and running lots of tests to see just how the library works, so stay tuned for more articles about this new library’s features.


Add commentAdd comment (Comments: 0)  

Advertisement

Partners

Related Resources

Other Resources

arrow