【问题标题】:Subclassing a jQuery object子类化一个 jQuery 对象
【发布时间】:2011-03-12 04:49:30
【问题描述】:

我想创建一个子类化的 jQuery 包装器,它包含 jQuery 的所有方法以及更多方法。我还想覆盖一些 jQuery 方法。这是我想要实现的示例

  calendar('.cal').showPopup()
                  .selectDate(new Date())
                  .addClass('popup-visible');
  alert(calendar.val());

请注意,日历就像 jQuery 对象一样工作除了

  • 它有一些额外的方法(showPopup 和 selectDate)
  • 它有一个被覆盖的方法 (val)
  • 使用方法链时,返回日历对象。这意味着 addClass 不应恢复为 jQuery 对象。

如果有人指出我正确的方向,我将不胜感激。我一直在玩范围和 $.extend 和原型,但似乎没有任何工作。

谢谢!

【问题讨论】:

    标签: jquery subclassing


    【解决方案1】:

    原来 jQuery 1.5 有一个新方法叫做 sub :)

    根据文档,子

    创建一个新的副本 jQuery 的属性和方法 可以修改而不影响 原始的 jQuery 对象。 http://api.jquery.com/jQuery.sub/

    此方法不允许您对子类进行子类化,但我在他们的票务跟踪器中发现了一个允许这样做的修改方法:

    jQuery.subclass = function(){
      function jQuerySubclass( selector, context ) {
        return new jQuerySubclass.fn.init( selector, context );
      }
      jQuery.extend(true, jQuerySubclass, this);
      jQuerySubclass.superclass = this;
      jQuerySubclass.fn = jQuerySubclass.prototype = this();
      jQuerySubclass.fn.constructor = jQuerySubclass;
      jQuerySubclass.fn.init = function init( selector, context ) {
        if (context && context instanceof jQuery && !(context instanceof jQuerySubclass)){
          context = jQuerySubclass(context);
        }
        return jQuery.fn.init.call( this, selector, context, rootjQuerySubclass );
      };
      jQuerySubclass.fn.init.prototype = jQuerySubclass.fn;
      var rootjQuerySubclass = jQuerySubclass(document);
      return jQuerySubclass;
    };
    

    这允许你做这样的事情:

    var Calendar = jQuery.subclass();
    Calendar.create = function() {
      var cal = Calendar( /* some html code for building the calendar */ );
    
      // Do some processing like binding events, etc
    
      return cal;
    }
    Calendar.fn.val = function(value) {
      //Calendar's implementation of val
    }
    

    Calendar 对象的作用就像 jQuery 对象一样除了 上面的那些差异。当我将方法链接在一起时,它也会正确返回一个 Calendar 实例。这很整洁,因为

    • 我们可以轻松构建自定义小部件 不会弄乱 jQuery 命名空间。
    • 我们可以提供自己的 jQuery 方法实现
    • 我们可以利用 jQuery 的强大功能,例如 trigger 和 bind 已经是类的一部分

    接下来,我对允许通过选择器注册类感兴趣。这样,当您调用 $('.MyAwesomeCalendar') 时,您将返回一个 Calendar 对象,而无需显式调用 Calendar('.MyAwesomeCalendar')。

    【讨论】:

    • 对于您的最后一条评论,关于由 css 类分配不同的子类,您是否正在寻找比重新定义 $.fn.init 更干净的东西?
    【解决方案2】:

    我首先要说的是,我认为您应该更深入地研究 jQuery 的 $.fn 插件方法。您可以在此处阅读更多信息:

    http://docs.jquery.com/Plugins/Authoring

    我会像这样完成上述操作:

    (function($){
      $.fn.calendar = function(){
        //do something useful
        return this; // necessary for chaining
      };
      $.fn.calendar.showPopup = function(){
        //do something useful
        return this; //necessary for chaining
      }
    )(jQuery);
    

    所以,话虽这么说。您上面的示例需要类似的语法才能将 jQuery 返回到您的 calendar 函数,并且必须返回 Calendar 的 this 以允许链接。我无法证明下面的代码,但这是一个好的开始:

    var Calendar = (function($){
      calendar = {
        showPopup : function($){
          //do something useful
          return $; //required for chaining
        },
        val : function($){
          //return your inherent functionality
          return $; //required for chaining
         }
    
      }  
    });
    var calendar = new Calendar(jQuery);
    

    就像我说的那样,这很丑陋,根本不应该怎么做。

    我不是 javascript 专家 - 但我相信这就是实现的方式。我也欢迎任何批评。

    【讨论】:

    • 感谢您的回答,但我正在寻找一种允许多态性的方法。例如,我创建的新小部件将具有不同的 val() 实现。
    • 不用担心。上面的答案非常出色,让我感到惊讶——我没有在新的 1.5 文档中看到该功能。看起来这正是你想要的!
    猜你喜欢
    • 2013-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-29
    • 1970-01-01
    • 2022-11-20
    • 1970-01-01
    • 2011-06-02
    相关资源
    最近更新 更多