0

I am learning how to create jQuery plugins and have built one using module pattern. It works if I apply it only once, however, if I apply multiple times, all of them get initialized using the last one's settings.

For instance, if I first do $('#div1').myPlugin();, and then later $('#div2').myPlugin({myProperty :'mydiv2Property'});, $('#div1') myProperty is changed from myDefaultProperty to mydiv2Property. The same thing happens when initializing with a different method.

I have a working (well, almost working!) example located at http://jsbin.com/eWePoro/1/, and my full script is listed below.

How do I change this script so each time the plugin is applied, it uses just its own properties and methods? Thank you

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
        <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" /> 
        <title>Testing</title>  
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js" type="text/javascript"></script>
        <style type="text/css">
        </style> 
        <script type="text/javascript"> 
            (function($){
                var defaults = {
                    myProperty  :'myDefaultProperty',
                    myMethod1   :function () {
                        console.log('myMethod1',this,this.myProperty);
                    },
                    myMethod2   :function () {
                        console.log('myMethod2',this,this.myProperty);
                    }
                };

                var methods = {
                    init : function (options) {
                        var settings = $.extend(defaults, options  || {});
                        settings.myMethod1();
                        return this.each(function () {
                            $(this).click(function(e) {
                                settings.myMethod2();
                            });
                        });
                    },
                    destroy : function () {
                        //Anything else I should do here?
                        delete settings;
                        return this.each(function () {});
                    }
                };

                $.fn.myPlugin = function(method) {
                    if (methods[method]) {
                        return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
                    } else if (typeof method === 'object' || ! method) {
                        return methods.init.apply(this, arguments);
                    } else {
                        $.error('Method ' +  method + ' does not exist on jQuery.myPlugin');
                    }    
                };

                }(jQuery)
            );
            $(function(){
                $('#div1').myPlugin();
                $('#div2').myPlugin({
                    myProperty  :'mydiv2Property'
                });
                $('#div3').myPlugin({
                    myMethod1   :function () {console.log('myMethod1_new',this,this.myProperty);}
                });
                 $('#div4').myPlugin({
                    myMethod2   :function () {console.log('myMethod2_new',this,this.myProperty);}
                });

            });
        </script>
    </head>

    <body>
        <div id='div1'>div1</div>
        <div id='div2'>div2</div>
        <div id='div3'>div3</div>
        <div id='div4'>div4</div>
    </body> 
</html> 
1
  • @zeroflagL. I think this was the document I originally used, but an older version. Can't be sure however, and I will re-read it again. Thanks Commented Dec 18, 2013 at 18:48

1 Answer 1

3

The problem is here:

var settings = $.extend(defaults, options  || {});

You are actually modifying defaults here with new properties. So next time you run the same code, defaults will be mutated. You should probably do:

var settings = $.extend({}, defaults, options);

This will create a new settings object every time by cloning defaults before extending it.

DEMO: http://jsbin.com/eWePoro/2

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

2 Comments

David, Your awesome! I originally got the faulting line of code from some tutorial (don't even remember were), and just never suspected it. Thanks!!!
Answer is perfect. If you see any other deficiencies in my script, please let me know.

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.