jQuery Plugin Namespace

后端 未结 5 1518
温柔的废话
温柔的废话 2020-12-23 18:18

How do I create a jQuery plugin so that I can use namespaces in my plugin ?

$(\"#id1\").amtec.foo1();
$(\"#id1\").amtec.foo2();

None of th

相关标签:
5条回答
  • 2020-12-23 18:56
     $.cg = {
      foo1: function(weq){
          return console.log(weq);
      },
      foo2: function(rw){
          return console.log(rw);
     }
    }; 
    $.cg = { // will result in error because $.cg is already declared above
    
      foo4: function(rw){ // will result in error
          return console.log(rw); // will result in error
     } // will result in error
    }; // will result in error
    
    $.cg.foo3 = function(weq){ //to add anything new to $.cg , you have to do it this way.
          return console.log(weq);
      }
    
    $.cg.foo1("12");
    $.cg.foo2("22"); //works fine.
    $.cg.foo3("112"); //works fine.
    
    0 讨论(0)
  • 2020-12-23 19:07
    (function($){
      $.namespace = function(ns, functions){
        $.fn[ns] = function() {return this.extend(functions)};
      };
      $.namespace('$', $.fn); // the default namespace
    })(jQuery);
    

    So now you can have a plugin:

    $.fn.func = function(){alert('plugin'); return this'};
    

    and create plugins in a namespace:

    $.namespace ('mynamespace', {
      func: function() {alert('namespaced plugin'); return this;},
      otherfunc: function() {return this.css('color', 'yellow');}
    });
    

    And if you do

    $('div').func(); // alerts 'plugin' -- no namespace
    

    But

    $('div').mynamespace().func(); // alerts 'namespaced plugin'
    

    And

    $('div').mynamespace().func().$().func(); // alerts 'namespaced
    

    plugin', then resets to the normal jquery and alerts 'plugin'

    0 讨论(0)
  • 2020-12-23 19:09

    I know I'm almost three years late to the party, but hopefully future readers of this question can benefit from my answer. The answer by GSto looks great from a jQuery plugin design standpoint, but has one small issue: calling mynamespace() clobbers the returned jQuery instance with new methods. Here is an example of that being an issue:

    $myDiv = $('.mydiv');
    $myDiv.mynamespace().height(); // this will be `height' from mynamespace
    $myDiv.height();               // this will STILL be `height' from mynamespace
                                   //   because it has overwritten $myDiv.height
    

    The chosen answer does not have this issue because there amtec() is not a jQuery instance and is instead an object that calls its methods with the jQuery instance as context. I have taken concepts from both answers and written the namespace plugin below:

    (function($) {
      $.namespace = function(namespaceName, closures) {
    
        if ($.fn[namespaceName] === undefined) {
          $.fn[namespaceName] = function executor(context) {
            if (this instanceof executor) {
              this.__context__ = context;
            }
            else {
              return new executor(this);
            }
          };
        }
    
        $.each(closures, function(closureName, closure) {
          $.fn[namespaceName].prototype[closureName] = function() {
            return closure.apply(this.__context__, arguments);
          };
        });
    
      };
    })(jQuery);
    

    Example usage:

    $.namespace('milosz', {
        redify: function() {
            $(this).css('color', '#ff0000');
        },
        greenify: function() {
            $(this).css('color', '#00ff00');
        }
    });
    
    $.namespace('milosz', {
        blueify: function() {
            $(this).css('color', '#0000ff');
        }
    });
    
    $('.mydiv').milosz().redify(); // The HTML elements with class `mydiv' are now red
    

    The code uses some pretty low-level details of JavaScript that are well-explained by John Resig's Advanced JavaScript tutorial, but loosely speaking what is happening in the example is this:

    When milosz (internally $.fn[namespaceName]) is called, this points to the jQuery instance returned by $('.mydiv'). Hence, the if statement falls through to the else block and the constructor version of milosz is called (referred-to internally as executor for reasons that are about to become apparent). The constructor is passed a single parameter: this, a pointer to the jQuery the instance that is going to be the execution context for all members of the milosz namespace. We enter back into the if statement, this time executing the first block, wherein the passed-in jQuery instance is stored in a member variable called __context__ (which hopefully has a low chance of being overwritten). The constructed object is returned, complete with a reference to the original jQuery instance and any wrappers added to its prototype by invocations of $.namespace. These wrappers simply execute the methods passed into the milosz namespace with the original jQuery object as context, as happens when redify is executed.

    Bah, I know it's a mouthful, anyway the point is it works like the accepted answer but looks like the jQueryish answer, which to me is the best of both worlds.

    0 讨论(0)
  • 2020-12-23 19:16
    (function($) {
        $.fn.amtec = function () {
            var jq = this;
            return {
                foo1: function(){
                    return jq.each(function(){});
                },
    
                foo2: function(){
                    return jq.each(function(){});
               }
           }
        };
    })(jQuery);
    
    0 讨论(0)
  • 2020-12-23 19:17

    I know it's an old question... But why write all this extra code when you can just replace . with _?

    $.fn.amtec_foo1 = function(){ return this.each(function(){}); }
    $.fn.amtec_foo2 = function(){ return this.each(function(){}); }
    

    Better yet, give your plugin a name that's original & project agnostic.

    $.fn.fooize = function(){ return this.html('Element has been Fooized!'); }
    
    0 讨论(0)
提交回复
热议问题