views:

58

answers:

2

I often saw this code in jQuery.

$('div').action1().delay(miliseconds).action2();

I could realize it in one level action in the following code.

function $(id) {
   var $ =  document.getElementById(id);

   $.action1 = function() {

   };

  return $;

}

How to write the method delay() and action2() so that I could use them this way?

$('div').action1().delay(miliseconds).action2();

+1  A: 

.delay() is used for animations

Sure there's other ways you can do this, but jQuery is chainable in an awesome way. That is, you don't have to write a bunch of anonymous functions or custom callbacks if you don't want to. Convenience in chaining!

On the other hand, if you actually want to customize the callbacks of animations, you can!

$('#foo').slideDown(500, function(){
  alert('foo is visible now!');
});

Check out the jQuery Effects API for more information.

It might be helpful to look at JavaScript's native setTimeout() function, too.

macek
+2  A: 

What you're referring to is called chaining. Aside from the fact that delay is used for animations, the key point to remember is to return this from your function.

If you'd like to see how specific jQuery functions work, check out the code for removeClass:

removeClass: function( value ) {
    if ( jQuery.isFunction(value) ) {
        return this.each(function(i) {
            var self = jQuery(this);
            self.removeClass( value.call(this, i, self.attr("class")) );
        });
    }

    if ( (value && typeof value === "string") || value === undefined ) {
        var classNames = (value || "").split(rspace);

        for ( var i = 0, l = this.length; i < l; i++ ) {
            var elem = this[i];

            if ( elem.nodeType === 1 && elem.className ) {
                if ( value ) {
                    var className = (" " + elem.className + " ").replace(rclass, " ");
                    for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
                        className = className.replace(" " + classNames[c] + " ", " ");
                    }
                    elem.className = jQuery.trim( className );

                } else {
                    elem.className = "";
                }
            }
        }
    }

    return this;
},

Notice the return this; at the end? That's allowing you to call $('#myelement').removeClass('highlight').someOtherFunction(), because at the end of the removeClass, you're still operating on the jQuery object itself.

If you'd like to examine other functions, check out the development version (unminified) of jQuery: http://code.jquery.com/jquery-1.4.2.js

Edit: to more fully answer your question, you can write your functions to allow chaining in the following way (include after your jQuery include):

(function($){
    $.fn.extend({
        action1: function() { return this; },
        action2: function() { return this; }
    })(jQuery);

This is essentially creating your own plugin. You can find a lot of tutorials online for how to do so, or open a plugin you already have an take a look at it.

Here is one simple tutorial: http://www.queness.com/post/112/a-really-simple-jquery-plugin-tutorial

Edit2: Without getting too far into creating jQuery plugins (since your questions is about javascript in general), I just wanted to mention that if you're doing a jQuery plugin, you'll want to do:
return this.each(function() {});
so your function performs on all elements chosen by the selector.

Jim Schubert