1

I'm creating a jQuery plugin that needs to do a bunch of stuff the first time it is called (and only the first time). The first time I need to build an index out of a part of the dom, I would only like to do that once and use that index the rest of the time.

Ideally I want it to work like so:

  1. The first time it's called, set run the function init() and set up all lots of var's which I need in the whole plugin (so I can't define them inside init() as they would be unavailable in the rest of the plugin).
  2. All the other times it is called it should use the vars already defined the first time.

First I tried this:

  $.fn.search = function() {  

    if( !inited ) {
    /*
        Define everything that should only be defined the first time
    */
    }

    /*
        All methods for my plugin, including an init() method
    */

    if( !inited ) {
        init();
        var inited = true;
    } 

 };

But I found out that every time the plugin is called all vars are gone, so that won't work. I know I can store stuff like so:

$.fn.search.config = {
    inited = false,
    output,
    search,
    singleElems,
    templates,
    included,
    scoreBoard,
    container,
    singles
}

And define them in init(), but is that the best way to store stuff for your plugin?

2 Answers 2

4

Use data, that's how most plugins do to store state and avoid duplicate initialization:

$.fn.search = function() {
    return this.each(function() { // For each selected element
        var data = $(this).data("search");
        if ( !data ) {
            var state = {};
            // Your plugin logic
            $(this).data("search",state);
        }
    });
};
Sign up to request clarification or add additional context in comments.

2 Comments

that's it, thanks! Note that this inside your closure is already a jQuery object, so you can just use this instead of $(this) (right?)
Yes, but remember that it is a collection of objects, with zero, one or more than one element. To be safe, use return this.each(function() { ... }); and put your code inside that function (in this case, this won't be a jQuery object, but an element, so you might have to use $(this))
2

You can use .data('myPluginData',{a:b,c:d}) (docs) to store all the settings you need in a single namespaced object that is attached to the element the plugin is applied to. See: http://docs.jquery.com/Plugins/Authoring#Data for the data part and http://docs.jquery.com/Plugins/Authoring#Plugin_Methods for the method calling logic.

This way you can easily keep track of the used setup and use things like if ($(this).data('myPluginData')) to find out if the plugin has already been called on any given object and just use sth like $(this).data('myPluginData').settingA to access the stored setup.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.