• A Plugin Development Pattern


    I've been developing jQuery plugins for quite a while now, and I've become rather comfortable with a particular style of plugin development for my scripts. This article is meant to share the pattern that I've found especially useful for plugin authoring. It assumes you already have an understanding of plugin development for jQuery; if you're a novice plugin author, please review the jQuery Authoring Guidelines first.

    There are a few requirements that I feel this pattern handles nicely:

    1. Claim only a single name in the jQuery namespace
    2. Accept an options argument to control plugin behavior
    3. Provide public access to default plugin settings
    4. Provide public access to secondary functions (as applicable)
    5. Keep private functions private
    6. Support the Metadata Plugin

    I'll cover these requirements one by one, and as we work through them we'll build a simple plugin which highlights text.

    Claim only a single name in the jQuery namespace

    This implies a single-plugin script. If your script contains multiple plugins, or complementary plugins (like $.fn.doSomething() and $.fn.undoSomething()) then you'll claim multiple names are required. But in general when authoring a plugin, strive to use only a single name to hold all of its implementation details.

    In our example plugin we will claim the name "hilight".

    PLAIN TEXT

    JavaScript:

    1. // plugin definition

    2. $.fn.hilight = function() {

    3. // Our plugin implementation code goes here.

    4. };

    And our plugin can be invoked like this:

    PLAIN TEXT

    JavaScript:

    1. $('#myDiv').hilight();

    But what if we need to break up our implementation into more than one function? There are many reasons to do so: the design may require it; it may result in a simpler or more readable implementation; and it may yield better OO semantics.

    It's really quite trivial to break up the implementation into multiple functions without adding noise to the namespace. We do this by recognizing, and taking advantage of, the fact that functions are first-class objects in JavaScript. Like any other object, functions can be assigned properties. Since we have already claimed the "hilight" name in the jQuery prototype object, any other properties or functions that we need to expose can be declared as properties on our "hilight" function. More on this later.

    Accept an options argument to control plugin behavior

    Let's add support to our hilight plugin for specifying the foreground and background colors to use. We should allow options like these to be passed as an options object to the plugin function. For example:

    PLAIN TEXT

    JavaScript:

    1. // plugin definition

    2. $.fn.hilight = function(options) {

    3. var defaults = {

    4.     foreground: 'red',

    5. background: 'yellow'

    6. };

    7. // Extend our default options with those provided.

    8. var opts = $.extend(defaults, options);

    9. // Our plugin implementation code goes here.

    10. };

    Now our plugin can be invoked like this:

    PLAIN TEXT

    JavaScript:

    1. $('#myDiv').hilight({

    2.   foreground: 'blue'

    3. });

    Provide public access to default plugin settings

    An improvement we can, and should, make to the code above is to expose the default plugin settings. This is important because it makes it very easy for plugin users to override/customize the plugin with minimal code. And this is where we begin to take advantage of the function object.

    PLAIN TEXT

    JavaScript:

    1. // plugin definition

    2. $.fn.hilight = function(options) {

    3. // Extend our default options with those provided.

    4. // Note that the first arg to extend is an empty object -

    5. // this is to keep from overriding our "defaults" object.

    6. var opts = $.extend({}, $.fn.hilight.defaults, options);

    7. // Our plugin implementation code goes here.

    8. };

    9. // plugin defaults - added as a property on our plugin function

    10. $.fn.hilight.defaults = {

    11.   foreground: 'red',

    12. background: 'yellow'

    13. };

    Now users can include a line like this in their scripts:

    PLAIN TEXT

    JavaScript:

    1. // this need only be called once and does not

    2. // have to be called from within a 'ready' block

    3. $.fn.hilight.defaults.foreground = 'blue';

    And now we can call the plugin method like this and it will use a blue foreground color:

    PLAIN TEXT

    JavaScript:

    1. $('#myDiv').hilight();

    As you can see, we've allowed the user to write a single line of code to alter the default foreground color of the plugin. And users can still selectively override this new default value when they want:

    PLAIN TEXT

    JavaScript:

    1. // override plugin default foreground color

    2. $.fn.hilight.defaults.foreground = 'blue';

    3. ...

    4. // invoke plugin using new defaults

    5. $('.hilightDiv').hilight();

    6. ...

    7. // override default by passing options to plugin method

    8. $('#green').hilight({

    9.   foreground: 'green'

    10. });

    Provide public access to secondary functions as applicable

    This item goes hand-in-hand with the previous item and is an interesting way to extend your plugin (and to let others extend your plugin). For example, the implementation of our plugin may define a function called "format" which formats the hilight text. Our plugin may now look like this, with the default implementation of the format method defined below the hilight function.

    PLAIN TEXT

    JavaScript:

    1. // plugin definition

    2. $.fn.hilight = function(options) {

    3. // iterate and reformat each matched element

    4. return this.each(function() {

    5. var $this = $(this);

    6.     ...

    7. var markup = $this.html();

    8. // call our format function

    9.     markup = $.fn.hilight.format(markup);

    10.     $this.html(markup);

    11. });

    12. };

    13. // define our format function

    14. $.fn.hilight.format = function(txt) {'

    15.   return '<strong>' + txt + '</strong>';

    16. };

    We could have just as easily supported another property on the options object that allowed a callback function to be provided to override the default formatting. That's another excellent way to support customization of your plugin. The technique shown here takes this a step further by actually exposing the format function so that it can be redefined. With this technique it would be possible for others to ship their own custom overrides of your plugin נin other words, it means others can write plugins for your plugin.

    Considering the trivial example plugin we're building in this article, you may be wondering when this would ever be useful. One real-world example is the Cycle Plugin. The Cycle Plugin is a slideshow plugin which supports a number of built-in transition effects נscroll, slide, fade, etc. But realistically, there is no way to define every single type of effect that one might wish to apply to a slide transition. And that's where this type of extensibility is useful. The Cycle Plugin exposes a "transitions" object to which users can add their own custom transition definitions. It's defined in the plugin like this:

    PLAIN TEXT

    JavaScript:

    1. $.fn.cycle.transitions = {

    2.   ...

    3. };

    This technique makes it possible for others to define and ship transition definitions that plug-in to the Cycle Plugin.

    Keep private functions private

    The technique of exposing part of your plugin to be overridden can be very powerful. But you need to think carefully about what parts of your implementation to expose. Once it's exposed, you need to keep in mind that any changes to the calling arguments or semantics may break backward compatibility. As a general rule, if you're not sure whether to expose a particular function, then you probably shouldn't.

    So how then do we define more functions without cluttering the namespace and without exposing the implementation? This is a job for closures. To demonstrate, we'll add another function to our plugin called "debug". The debug function will log the number of selected elements to the Firebug console. To create a closure, we wrap the entire plugin definition in a function (as detailed in the jQuery Authoring Guidelines).

    PLAIN TEXT

    JavaScript:

    1. // create closure

    2. (function($) {

    3. // plugin definition

    4.   $.fn.hilight = function(options) {

    5.     debug(this);

    6.     ...

    7. };

    8. // private function for debugging

    9. function debug($obj) {

    10. if (window.console && window.console.log)

    11.       window.console.log('hilight selection count: ' + $obj.size());

    12. };

    13.   ...

    14. // end of closure

    15. })(jQuery);

    Our "debug" method cannot be accessed from outside of the closure and thus is private to our implementation.

    Support the Metadata Plugin

    Depending on the type of plugin you're writing, adding support for the Metadata Plugin can make it even more powerful. Personally, I love the Metadata Plugin because it lets you use unobtrusive markup to override plugin options (which is particularly useful when creating demos and examples). And supporting it is very simple!
    Update: This bit was optimized per suggestion in the comments.

    PLAIN TEXT

    JavaScript:

    1. // plugin definition

    2. $.fn.hilight = function(options) {

    3.   ...

    4. // build main options before element iteration

    5. var opts = $.extend({}, $.fn.hilight.defaults, options);

    6. return this.each(function() {

    7. var $this = $(this);

    8. // build element specific options

    9. var o = $.meta ? $.extend({}, opts, $this.data()) : opts;

    10.     ...

    This changed line does a couple of things:

    • it tests to see if the Metadata Plugin is installed
    • if it is installed, it extends our options object with the extracted metadata.

    This line is added as the last argument to jQuery.extend so it will override any other option settings. Now we can drive behavior from the markup if we choose:

    <!--  markup  -->
    <div class="hilight { background: 'red', foreground: 'white' }">
      Have a nice day!
    </div>
    <div class="hilight { foreground: 'orange' }">
      Have a nice day!
    </div>
    <div class="hilight { background: 'green' }">
      Have a nice day!
    </div>
    

    And now we can hilight each of these divs uniquely using a single line of script:

    PLAIN TEXT

    JavaScript:

    1. $('.hilight').hilight();

    Putting it All Together

    Below is the completed code for our example:

    PLAIN TEXT

    JavaScript:

    1. //

    2. // create closure

    3. //

    4. (function($) {

    5. //

    6. // plugin definition

    7. //

    8.   $.fn.hilight = function(options) {

    9.     debug(this);

    10. // build main options before element iteration

    11. var opts = $.extend({}, $.fn.hilight.defaults, options);

    12. // iterate and reformat each matched element

    13. return this.each(function() {

    14.       $this = $(this);

    15. // build element specific options

    16. var o = $.meta ? $.extend({}, opts, $this.data()) : opts;

    17. // update element styles

    18.       $this.css({

    19.         backgroundColor: o.background,

    20.         color: o.foreground

    21. });

    22. var markup = $this.html();

    23. // call our format function

    24.       markup = $.fn.hilight.format(markup);

    25.       $this.html(markup);

    26. });

    27. };

    28. //

    29. // private function for debugging

    30. //

    31. function debug($obj) {

    32. if (window.console &amp;&amp; window.console.log)

    33.       window.console.log('hilight selection count: ' + $obj.size());

    34. };

    35. //

    36. // define and expose our format function

    37. //

    38.   $.fn.hilight.format = function(txt) {

    39. return '<strong>' + txt + '</strong>';

    40. };

    41. //

    42. // plugin defaults

    43. //

    44.   $.fn.hilight.defaults = {

    45.     foreground: 'red',

    46. background: 'yellow'

    47. };

    48. //

    49. // end of closure

    50. //

    51. })(jQuery);

    This design pattern has enabled me to create powerful, consistently crafted plugins. I hope it helps you to do the same.

    42 Responses to “A Plugin Development Pattern”
    1. Nmweb Says:
      October 30th, 2007 at 3:38 pm

      Great tutorial. Thanks, I was hoping to delve into jQuery plugins someday and this will be a great help. These were indeed the issues I would run into.

    2. Stan Says:
      October 30th, 2007 at 3:39 pm

      Great article! Thanks for posting it. And thank you for all the work you've contributed to the jQuery community.

      Pax,
      - Stan

    3. Byron Says:
      October 30th, 2007 at 7:56 pm

      Nice pattern & article Mike, I especially like the last two pointers (private functions and support metadata) as they are something i felt i was lacking an understanding of. thanks for clearing that up :-).

    4. Joan Piedra Says:
      October 30th, 2007 at 8:21 pm

      I love the way you implemented the metadata plugin, I've been using it for a while, but never thought about implementing it with extend!

      Thanks for such a great guide.

    5. Guy Fraser Says:
      October 30th, 2007 at 11:20 pm

      First of all, superb tutorial!

      However, the following line of code seems to be getting run excessively:

      var opts = $.extend({}, $.fn.hilight.defaults, options, $.meta ? $this.data() : {});

      That's a lot of object iterating to do on an element-by-element basis IMHO, especially if the metadata plugin isn't installed.

      What if you changed it slightly...

      
      $.fn.hilight = function(options) {
          debug(this);
      
          // work out main settings (without metadata) - only do this work once per plugin call
          var main_opts = $.extend({}, $.fn.hilight.defaults, options);
      
          // iterate and reformat each matched element
          return this.each(function() {
            $this = $(this);
      
            // if metadata is present, extend main_opts, otherwise just use main_opts
            var opts = $.meta ? $.extend({}, main_opts, $this.data()) : main_opts;
      
            // update element styles
      
            ... etc
      

      Feedback?

    6. roScripts - Webmaster resources and websites Says:
      October 31st, 2007 at 6:15 am

      Learning jQuery » A Plugin Development Pattern...

      Learning jQuery » A Plugin Development Pattern...

    7. Mike Alsup Says:
      October 31st, 2007 at 6:29 am

      That's a fine optimization, Guy. Thanks!

    8. James Dempster Says:
      October 31st, 2007 at 7:58 am

      Wow a fantastic tutorial on how to write jQuery plugins. That's exactly how every one should do it. Glad I've been doing it right all this time ;¬)

    9. Tane Piper Says:
      October 31st, 2007 at 11:06 am

      I've been doing most of what you are suggesting already, but there are a few things (like making default options public and using the meta plugin) that I was missing, I'll be upgrading my plugins to include these :)

    10. Guy Fraser Says:
      October 31st, 2007 at 11:08 am

      The if statement in the debug function seems to have the && chimped...

    11. Ariel Flesler Says:
      October 31st, 2007 at 11:52 am

      Great article !!

    12. Guy Fraser Says:
      October 31st, 2007 at 3:41 pm

      Just found another minor optimisation with respect to /packer/ - you can prefix variables to reduce the length of their names:

      http://dean.edwards.name/packer/2/usage/#special-chars

      This is probably overkill for the tutorial, however as lots of people will be looking at this page it's worth increasing knowledge of this feature of the packer.

      So, some tweaks for extra packing goodness:

      
            //
            // create closure
            //
            (function($) {
              //
              // plugin definition
              //
              $.fn.hilight = function($$options) {
                ;;; _debug(this);
      
                // build main options before element iteration
                var $settings = $.extend({}, $.fn.hilight.defaults, $$options);
      
                // iterate and reformat each matched element
                return this.each(function() {
                  $this = $(this);
                  // build element specific options
                  var o = $.meta ? $.extend({}, $settings, $this.data()) : $settings;
                  // update element styles
                  $this.css({
                    backgroundColor: o.background,
                    color: o.foreground
                  });
                  var $markup = $this.html();
                  // call our format function
                  $markup = $.fn.hilight.format($markup);
                  $this.html($markup);
                });
              };
      
              //
              // private function for debugging
              //
              function _debug($obj) {
                if (window.console && window.console.log)
                  window.console.log('hilight selection count: ' + $obj.size());
              };
      
              //
              // define and expose our format function
              //
              $.fn.hilight.format = function($txt) {
                return '' + $txt + '';
              };
      
              //
              // plugin defaults
              //
              $.fn.hilight.defaults = {
                foreground: 'red',
                background: 'yellow'
              };
            //
            // end of closure
            //
            })(jQuery);
      

      You do have to be super-careful with $ prefixes though. For example, $options and $opts are both packed to "o" (which was already in use lower down the code). To get round that I've used two $$ for the options parameter (packed to "op") and renamed opts to $settings (packed to "s").

      I've renamed debug to _debug (packed to _0 - that's a zero, not an "o") and also put three semicolons (;;;) before the call to debug(this) - the packed version would omit that line completely.

      It's a shame that Dean Edwards' packer isn't based on Rhino - that way he'd be able to work out automatically with very high accuracy which vars are local or private. I believe Jack Slocum's ExtJS packer is based on Rhino and does this, however I haven't tried it to see if it works.

    13. Scriptia Says:
      November 2nd, 2007 at 8:31 am

      Un patrón de desarrollo de plugins para jQuery...

      Mike Alsup, autor de jQuery form plugin y otras delicias, nos explica cómo crear un plugin para jQuery que cumpla con las condiciones de: no contaminar el espacio de nombres, acepte opciones (y las extienda), mantenga los límites adecuados entre lo p...

    14. Mario Garcia Says:
      November 27th, 2007 at 5:20 pm

      Hi Mike.
      Great job !!!! ( Sorry for my english)
      and, a couple of questions:
      * how I can implement Statics Methods/Attributes ?
      * how I can implement Inheritance?
      for example:
      Person is superclass for employee.
      Thank's :)
      Mario Garcia

    15. dnk.nitro Says:
      November 30th, 2007 at 7:50 pm

      After update of metadata plugin consider using
      var o = $.metadata ? $.extend({}, opts, $this.metadata()) : opts;
      code instead in line 18

    16. Ismael Says:
      December 1st, 2007 at 6:00 pm

      It DOES help a lot! Thank you for an excellent tutorial.

    17. Andy Croll Says:
      December 18th, 2007 at 10:12 pm

      Is there a sensible way to set variables or run functions within the already running plugin?

    18. Omar Abdel-Wahab Says:
      January 2nd, 2008 at 10:55 am

      Hi Mike and thanks for the tutorial, yet I have a single comment: using $ instead of jQuery inside your plugin isn't recommended, IMO, since it will mean users trying to rename "$" to anything else will not be able to do that from a single location.
      Read: http://docs.jquery.com/Plugins/Authoring#Custom_Alias

    19. Karl Says:
      January 2nd, 2008 at 11:53 am

      Hi Omar,
      If you look at Mike's last code example (in "Putting it all together"), you'll see that he does exactly what the author of your link recommends:

      (function($) {
      
        // plugin code
      
      })(jQuery);
    20. Alexandre Magno Says:
      January 22nd, 2008 at 2:33 pm

      I saw a lot of plugins that uses object notation, how should behave this way?

      $.extend({

      somefunction: function(test) {

      //somecode goes here

      }

      });

    21. Adam T. Says:
      January 25th, 2008 at 3:48 pm

      Why might I need to wrap my calling statement like the following:

      
      $(function () {
        $('#myDiv').myMethod();
      });

      Ideally I'd like to get away from having a wrapper in my code and instead just call

      $('#myDiv').myMethod();

      directly. Unfortunately, it seems as though my code doesn't work unless I wrap it in this way.

    22. Josh Kline Says:
      January 31st, 2008 at 1:46 am

      Adam T,

      $(function () { ... }); is a shortcut for $(document).ready(function () { ... });

      That is roughly equivalent to <body onload="...">. The purpose is to run your jQuery code after the entire page has loaded, included jQuery itself, and the dom is ready for manipulation.

      There are plenty of tutorials on the basics of jQuery, but this post is not one of them. You might want to check out docs.jquery.com or some other posts on this site.

    23. Adrien Says:
      February 15th, 2008 at 2:14 am

      Bravo!

      This is a great tutorial, usefull for beginner to confirmed jQuery developpers...

      Explanation are crystal clear... you rocks!

      Just a explanation for those who start jQuery:
      In
      var o = $.metadata ? $.extend({}, opts, $this.metadata()) : opts;

      "$.extend({}, opts, $this.metadata())" returns a new object extending opts with $this.metadata() without modifying opts

      as the first argument of $.extends is like passed by reference, using {} will return a brand new object.

      using "$.extend(opts, $this.metadata())" will modify the general options witch is not wanted...

      my two coins

    24. christian Says:
      February 18th, 2008 at 7:59 pm

      GREAT TUTORIAL ... this really got me motivated to play around with jquery plugins.
      One point i am curious about. What do you think of exposing the format-function not via $.fn.highlight.format but as another attribute of the options. So the format function can be changed globally in the defaults or locally for one jquery call, as the other primitive types in the options.

    25. Frink Says:
      March 5th, 2008 at 5:11 pm

      I propose a slight alteration to the namespace convention suggested above. It is already in widespread use among plugin developers. In creating long chains for complicated processes in jQuery the pater is:

      $('selector').method().method().method() etc...

      If we use the above recommendation it becomes:

      $('selector').namespace.method().namespace.method().namespace.method() etc...

      This is over-prototyping and bad coding practice. It would be better to use a namespace-prefix instead. consider:

      $('selector').namespaceMethod().namespaceMethod().namespaceMethod() etc...

      In the case of re-render function where manipulates or changes the HTML two functions should be provided. You should provide a function to reverse any destructive operation you do. For re-rendering use (/un)namespaceMethod(). For manipulation use (add/remove)Namspace().

      $('selector').namespaceMethod();
      $('selector').unnamespaceMethod();
      $('selector').addNamespaceMethod();
      $('selector').removeNamespaceMethod()

      This naming convention is used all over jQuery already. These re-render and manipulation functions should always return a jQuery object so that chaning may continue. If you need to use a return code consider setting a context persistent variable in the DOM.

      You should provide a global object rather than extending the prototype object. Consider:

      $.namespace

      instead of:

      $.fn.namespace

      This allows a more accurate representation of data. The global default settings are stored as part of the global default object. The manipulation and render functions are part of the prototyped jQuery select. Also the defaults should not be prototyped. It is better to render the options as a child of the global namespace.

      Finally, initialization was not discussed in this article. Often plugins may wish to initialize on document ready. This should be put after the prototype section of the plugin.

      Altogether a pulgin template should look like this:


      (function($) {
      // Private Variables and Functions
      var privateVariable = {};
      function privateFunction() {
      };
      // Public Variables and Methods
      $.namespace = {
      options: {},
      publicVariable: [];
      publicMethod: function() {}
      };
      // Prototype Methods
      $.fn.extend({
      usernameMethod: function() {
      return this.each(function() {
      // Persistent Context Variables
      this.contextVariable = 'foo';
      }
      }.
      unusernameMethod: function() {
      return this.each(function() {
      delete this.contextVariable;
      }
      }
      });
      //Initialization Code
      $(function() {
      });
      })(jQuery);

      Prototype variables should variables should be avoided. If a context specific variable is required you should use the each() construct and set the variable to this.namespaceVariable. In this way you are using the native DOM construct for variable settings.

      Finally, it is generally considered good etiquette to put a usage information in a comment aat the head of your script file along with author attribute, copyright, version and source repository information. That way developers can easily find where to submit bug reports and change ideas.

    26. Frink Says:
      March 5th, 2008 at 8:49 pm

      There are errors in my code above. I was typing fast and my connection froze when I tried to go back and edit it. The skeleton template should have been rendered:


      (function($) {

        // Private Variables and Functions
        var privateVariable = {};
        function privateFunction() {
          // Do Something Privately
        };

        // Public Variables and Methods
        $.namespace = {
          options: {},
          publicVariable: [],
          publicMethod: function() {
            // Do Something Publicly
          }
        };

        // Prototype Methods
        $.fn.extend({
          namespaceMethod: function() {
            return this.each(function() {
              // Example Setting Persistent DOM Variables
              this.contextVariable = 'foo';
            });
          },
          unnamespaceMethod: function() {
            return this.each(function() {
              // Example Removing Persistent DOM Variables
              delete this.contextVariable;
            });
          }
        });

        //Initialization Code
        $(function() {
          $.namespace.publicMethod();
        });

      })(jQuery);

      One final note. Although this isn't standard practice, you can greatly clarify your code by using a private object as opposed to using free-floating private functions and variable. The the private section would therefore look like this:


        // Private Variables and Functions
        var private = {
          privateVariable: {},
          function privateFunction() {
            // Do Something Privately
          }
        };

      This way when you access private variables and methods it will be apparent in your code:


      private.privateVariable = 'foo';
      private.privateMethod('bar');

    27. Frink Says:
      March 5th, 2008 at 9:22 pm

      One more oops. Low blood sugar. Wasn't thinking. You should not use "private" as a variable name. instead you can use the namespace you choose.


      // Private Variables and Methods
      var namespace = {
      };
      // Public Variables and Methods
      $.namespace {
      }

      Sorry for the confusion. Argh! I hate not thinking straight.

    28. malsup Says:
      March 6th, 2008 at 8:05 am

      Frink,

      I'm most definitely not suggesting anyone using namespacing to do this:

      $('selector').namespace.method().namespace.method().namespace.method()

      As was mentioned, this article focuses on a single-plugin script and the suggestion is to use a single namespace for a single plugin. If your script has multiple plugins then you certainly need multiple $.fn extension points (for example, $.fn.doSomething() and $.fn.undoSomething()).

      I believe that using the plugin function for default settings and for exposing public functions is a better implementation than extending the jQuery object itself. I suppose it's a matter of taste, but I prefer to have the entire plugin implementation packaged in the same namespace.

    29. Kean Says:
      March 12th, 2008 at 7:17 pm

      Thanks for the post. I just developed a plugin and I will implement the patterns.

    30. Alexandre Plennevaux Says:
      March 18th, 2008 at 7:01 am

      Hi Mike,
      thanks for this most excellent and referential tutorial!

      Could you update it to explain how to implement callbacks? Some concise background info about callbacks would be great as well.

      Thank you so so much for all you do for the jquery community!

      Alexandre

    31. Alexandre Magno Says:
      March 28th, 2008 at 10:24 am

      Im working in a big project of ajax and I would like to use a plugin
      pattern thats not working in pratice...

      All javascript in the project I would like to transform in a jQuery
      plugin. But to achieve this I need to separate in categories in
      libraries for this site Im working

      So, I wanna to make this:

      $("seletor").project.ajax.remote();

      $("seletor").helpers.options();

      But when Im creating a plugin like this:

      $.fn.project.ajax.remote = function() {
      //code

      }

      Its not working...

      Using extend I reach it, but extending methods of jQuery objects I
      cant do that. I need this because I create a ajax library just for the
      site and a lot of thing, so we need this pattern...

      How I can accomplish this????

    32. Edilson de Souza Says:
      March 30th, 2008 at 11:31 pm

      Hails! Mike, I've been writing a plugin and I wanna know about the flexibility of writing in a OO manner, like so:
      (function($){
          $.myClassName = {

              calcSomething: function(arg){
                  //do something
              },

              main: function(){

      return

      this.each(function(){
                      //do something more
                      $.myClassName.calcSomething(param){

                 }
              }
          }
          $.fn.myMethod = $.myClassName.main;
      })(jQuery);

      I'd like to know your opinion about that OO pattern in jQuery plugins.
      Thanks for your article!

    33. michael Says:
      April 16th, 2008 at 1:44 pm

      I looked at different plugins code and this is definitely the best plugin pattern I found. Many thanks for that great tutorial!!

    34. Brian Says:
      May 2nd, 2008 at 9:17 am

      Hi! That was a great article, but I still have a question:
      If you extend the options this way and the user doesn't set all the new defaults then some options may be missing that can easily cause problem (as they will be undefined). If each properties are set it doesn't matter but only if a new object is given as defaults, which is more convenient in most cases.
      So, wouldn't be better:

      //defaults inside the plugin:
      var defaults = {
      foreground: 'red',
      background: 'yellow'
      };

      $.extend( defaults, $.fn.pluginName.defaults, options )

    35. Website Design Says:
      June 2nd, 2008 at 2:55 pm

      I almost always enjoy what I read on this site. :)

    36. Junaidix Says:
      July 25th, 2008 at 4:27 am

      Wow.. this a great article.. I'm really novice in Jquery world. Just to leant to write my first plugin :) Thanks for the tutorial..

    37. ze Says:
      August 7th, 2008 at 4:03 am

      i love this tutorial, very thanks it's helpfull!

    38. Andre Says:
      August 26th, 2008 at 12:18 pm

      I had to var the $this on line 16 of the putting it all together list to get it to work right when setting up a binding on an element.

      Also, I seem to not have access to opts in from within the getformat function on line 42. Is there a trick to accessing it?

      $.fn.hilight.format = function(txt) {
      alert(opts) //fails
      return '' + txt + '';
      };

    39. mark meves Says:
      August 31st, 2008 at 1:45 am

      One thing I don't get here, near all of the examples with a line like

        return this.each(function() {
          var $this = $(this); ...

      After that last line, $this is now an array, isn't it? In the examples, it isn't used as an array. What am I missing?

    40. mark meves Says:
      August 31st, 2008 at 5:59 am

      Ok disregard my above comment -- i shouldn't have spoken too soon. I have since learned that this is lesson 101 of jquery -- we frequently deal with lists of elements

    41. Gaurav Says:
      September 25th, 2008 at 5:47 am

      Excellent tutorial !!! Very helpful i created my first plug-in today.
      Will post it very soon on my blog.

      G

    42. Neva Says:
      September 28th, 2008 at 8:01 pm

      jQuery very good!


  • 相关阅读:
    Codeforces 1082 毛毛虫图构造&最大权闭合子图
    BZOJ 1003 最短路dp
    BZOJ 1002 生成树计数&高精度
    BZOJ 1001 平面图转对偶图
    BZOJ 世界树
    一般图极大团个数,最大团顶点数
    第十五届四川省省赛 SCU
    第十五届四川省省赛 SCU
    第十五届四川省省赛 SCU
    BZOJ4671异或图
  • 原文地址:https://www.cnblogs.com/HeroBeast/p/1306267.html
Copyright © 2020-2023  润新知