1

I'm beginning with jQuery plugins, apologies for the newbie question. My objective is to have a single plugin instantiated twice, where each instance has its own variables values. However, they seem to share the namespace.

For example, given the following plugin:

(function ( $ ) {

    var x = false;

    $.fn.test = function() {

        alert(x);

        if ( !x )
           x = true;

        return this;

    };

}( jQuery ));

that is invoked from the following divs:

$( "div1" ).test();
$( "div2" ).test();

The alert displays first false, then true, when the objective is to have to sets of variables where the alert would display false twice.

is this possible?

1

3 Answers 3

2

There is some confusion in your question. Your plugin is a simple function. You don't "instantiate" a function by calling it. So you don't "instantiate" your plugin either.

You can instantiate things in your function, and persist them somewhere.

Since the outer scope runs only once, in your original solution you only get one instance of variable x.

If you create it inside the function, a new instance gets created every time you call it.

I assume you want to create an instance for every element you call this plugin on. A good solution would be to attach your data to the DOM element you initiate your plugin on, like:

(function ( $ ) {
    $.fn.test = function() {
        var vars = this.data('testPlugin');
        if (!vars) {
            vars = {
                x: false,
                something: 'else'
            };
            this.data('testPlugin', vars);
        }

        alert(vars.x);
        vars.x = !vars.x;

        return this;
    };
}( jQuery ));

Try this fiddle.

Sign up to request clarification or add additional context in comments.

1 Comment

thanks, I said "instantiate" because I see the plugin as an object with attributes and functions.
0

You should put

var x = false;

inside $.fn.test function, otherwise the x variable is the same for all test() functions, and set to true after first call.

You can read more here about javascript variable scoping.

1 Comment

Thanks, but it didn't work. I put var x = false; inside $.fn.test function and obviously the variable is always set to false, not only after the first call.
0

Actually, this is much easier than the previous answers. The context of this in your plugin is the jQuery object for the DOM element you're receiving based on the selector you provided. To gain uniqueness, simply iterate over each element, like so:

(function($) {
  $.fn.test = function() {
    return this.each(function() {
      var x = false;

      alert(x);

      if (!x) {
        x = true;
      } 
    });
  }
}(jQuery));

$("div1").test();  //false
$("div2").test();  // false

Here's a JSFiddle to confirm: http://jsfiddle.net/Z6j7f/

2 Comments

alert(x) will always alert false here, and since nothing else accesses the inner scope the if... part is completely unnecessary since nothing else will access x ever. Is this intended? return this.each(function () { alert(false); }); would do exactly the same.
From my interpretation of the original problem posted, the conditional check was arbitrary and used to evaluate if the state of x changed. I would agree with you that the condition is unnecessary.

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.