【问题标题】:jQuery Plugin Namespacing FunctionsjQuery 插件命名空间函数
【发布时间】:2009-08-02 19:35:49
【问题描述】:

我正在创建一个范围相当大的 jQuery 插件。事实上,从技术上讲,该插件由几个共同工作的插件组成。

(function($){
    $.fn.foo = function(){
        //plugin part A
    }
    $.fn.bar = function(){
        //plugin part B
    }
    $.fn.baz = function(){
        //plugin part C
    }
}(jQuery))

是否可以命名 jQuery 插件,以便次要插件可以是较大插件的功能

$.fn.foo.bar = function(){}
$.fn.foo.baz = funciton(){}

这样可以避免污染 jQuery 函数命名空间。 然后你可以调用插件像

$('#example').foo()
$('#other_example').foo.bar()

我自己尝试这个时遇到的问题是声明为 foo() 插件函数的属性的函数没有正确设置它们对“this”的引用。 'this' 最终指向父对象而不是 jQuery 对象。

任何想法或意见将不胜感激。

-马特

【问题讨论】:

    标签: javascript jquery jquery-plugins


    【解决方案1】:

    只要你使用$.fn.foo.bar() -- this 指向$.fn.foo,这就是你在 JavaScript 中所期望的(this 是调用函数的对象。)

    我注意到 jQuery UI 的插件(如可排序)中调用的函数如下:

    $(...).sortable("serialize");
    $(...).sortable({options});
    

    如果你正在做这样的事情 - 你可以扩展 jQuery 本身:

    $.foo_plugin = {
      bar: function() {},
      baz: function() {}
    }
    
    $.fn.foo = function(opts) {
      if (opts == 'bar') return $.foo_plugin.bar.call(this);
      if (opts == 'baz') return $.foo_plugin.baz.call(this);
    }
    

    【讨论】:

    • 我以前从未看过 jQuery UI 库。但这是一个非常有趣且适用的解决方案。谢谢。
    【解决方案2】:

    我知道这个问题已经得到解答,但我创建了一个完全符合您要求的插件:

    http://code.google.com/p/jquery-plugin-dev/source/browse/trunk/jquery.plugin.js

    我在下面包含了一个小示例,但请查看此 jQuery Dev Group 帖子以获得更深入的示例:http://groups.google.com/group/jquery-dev/browse_thread/thread/664cb89b43ccb92c/72cf730045d4333a?hl=en&q=structure+plugin+authoring#72cf730045d4333a

    它允许您使用任意数量的方法创建对象:

    var _myPlugin = function() {
        // return the plugin namespace
        return this;
    }
    
    _myPlugin.prototype.alertHtml = function() {
        // use this the same way you would with jQuery
        alert($(this).html());
    }
    
    $.fn.plugin.add('myPlugin', _myPlugin);
    

    现在你可以走了:

    $(someElement).myPlugin().alertHtml();
    

    当然,如开发组帖子中所述,还有很多其他可能性。

    【讨论】:

      【解决方案3】:

      嗯,我敢肯定有很多方法可以给这只猫剥皮。 jQuery UI 库使用这样的模式:

      // initialize a dialog window from an element:
      $('#selector').dialog({});
      
      // call the show method of a dialog:
      $('#selector').dialog('show');
      

      【讨论】:

      • 就个人而言,我认为这种方式是一种“肮脏”的黑客攻击,因为他们不能使用 $('#selector').dialog().show(),但它是另一种方法。
      【解决方案4】:

      我喜欢在 Eric Martin 的SimpleModal 上看到的模式。当我不对 DOM 元素进行操作时,这很有效——在这种情况下是一个使用 localStorage 的包装器。

      这样我就可以很方便的引用构造函数了:

      $.totalStorage('robo', 'cop');
      

      ...或公共方法:

      $.totalStorage.getItem('robo'); //returns 'cop'
      

      这是内部结构:

      ;(function($){
      
      /* Variables I'll need throghout */
      
      var ls;
      var supported = true;
      if (typeof localStorage == 'undefined' || typeof JSON == 'undefined') {
          supported = false;
      } else {
          ls = localStorage;
      }
      
      /* Make the methods public */
      
      $.totalStorage = function(key, value, options){
          return $.totalStorage.impl.init(key, value);
      }
      
      $.totalStorage.setItem = function(key, value){
          return $.totalStorage.impl.setItem(key, value);
      }
      
      $.totalStorage.getItem = function(key){
          return $.totalStorage.impl.getItem(key);
      }
      
      /* Object to hold all methods: public and private */
      
      $.totalStorage.impl = {
      
          init: function(key, value){
              if (typeof value != 'undefined') {
                  return this.setItem(name, value);   
              } else {
                  return this.getItem(name);
              }
          },
      
          setItem: function(key, value){
              if (!supported){
                  $.cookie(key, value);
                  return true;
              }
              ls.setItem(key, JSON.stringify(value));
              return true;
          },
      
          getItem: function(key){
              if (!supported){
                  return this.parseResult($.cookie(key));
              }
              return this.parseResult(ls.getItem(key));
          },  
      
          parseResult: function(res){
              var ret;
              try {
                  ret = JSON.parse(res);
                  if (ret == 'true'){
                      ret = true;
                  }
                  if (ret == 'false'){
                      ret = false;
                  }
                  if (parseFloat(ret) == ret){
                      ret = parseFloat(ret);
                  }
              } catch(e){}
              return ret;
          }
      }})(jQuery);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-03-02
        • 2012-09-19
        • 2010-11-19
        • 2012-02-21
        • 2014-03-09
        • 2023-03-17
        • 2012-10-13
        • 1970-01-01
        相关资源
        最近更新 更多