views:

38

answers:

1

I would like to create a jQuery plugin with an API something like this:

$("#chart").pluginName().attr("my_attr");

Instead of these:

$("#chart").pluginName_attr("my_attr");
$.pluginName.attr("#chart", "my_attr");

Basically, instead of having to namespace every method that acts similar to ones in jQuery, I'd like to "scope" the methods to a custom api, where $("#chart).pluginName() would return an object such that get, attr, find, and a few others would be completely rewritten.

I'm sure this is not a well-liked idea as it breaks convention (does it?), but it's easier and more readable, and probably more optimized, than the two options above. What are your thoughts?

+2  A: 

I'm experimenting with the idea.

Seems like you could just modify the functions for the jQuery object that the plugin receives, and return that.

Something like this:

$.fn.tester = function() {  // The plugin

    this.css = function() {  // Modify the .css() method for this jQuery object
        console.log(this.selector);   // Now it just logs the selector
        return this;     // Return the modified object
    }
    return this;   // Return the modified object

}

http://jsfiddle.net/EzzQL/1/ (updated from original to overwrite .html() as well)

$.fn.tester = function() {
    this.css = function() {  
        console.log(this.selector);  // This one logs the selector
        return this;
    }
    this.html = function() {
        alert(this.selector); // This one alerts the selector
        return this;
    }
    return this;
};

// Because .css() and .html() are called after .tester(),
// they now adopt the new behavior, and still return a jQuery
//    object with the rest of the methods in tact
$('#test1').tester().css().html().animate({opacity:.3}); 


// .css() and .html() still behave normally for this one
//    that doesn't use the plugin
$('#test2').css('backgroundColor','blue').html('new value');​

EDIT:

Alternatively, if you're going to cache the elements to which the custom methods should be applied, you could .apply() the methods before you use them.

To build on the example above:

var $test1 = $('#test1');  // Cache the elements

$.fn.tester.apply($test1,[this]);  // apply() the new methods

$test1.css().html().animate({opacity:.3});  // Use the new methods

patrick dw