扩展 jQuery 插件的最佳方式

Posted

技术标签:

【中文标题】扩展 jQuery 插件的最佳方式【英文标题】:Best Way to Extend a jQuery Plugin 【发布时间】:2011-01-04 07:00:31 【问题描述】:

我是一个相当新的 jQuery 用户,希望扩展一个现有的 jQuery 插件,它可以完成我需要的 75% 的工作。我试图在这方面做我的功课。我在 *** 上查看了以下问题:

Extending a jQuery Plugin Extend a jQuery Plugin jQuery: extend plugin question

我在 extend 方法上有 read up。然而,所有这些作业都让我感到困惑。我正在使用fullcalendar 插件,需要修改一些行为以及添加新的事件挂钩。我是否坚持在插件闭包本身中执行此操作?我错过了什么明显的东西吗?

理想情况下,我们可以将我们的代码与插件代码分开,以便进行可能的升级。任何帮助将不胜感激,尤其是关于我在哪些地方缺少一些关于其他 Stack Overflow 问题中已经提出的解决方案是否有意义的信息或意见的指针。对我来说,它们相互矛盾,我仍然感到困惑。

【问题讨论】:

justkt,你能发布一些你如何扩展全日历插件的示例代码吗?我目前正在尝试做同样的事情,但我被难住了,无法调用我应该添加的任何函数。 @MattMcCormick - 您是否尝试过下面列出的公认答案? 啊,我包括了 .prototype。我不需要那个。现在我只有 $.extend(true, $.fullCalendar, extensionMethods);它有效!理想情况下,我想扩展 Event 对象,但它没有命名空间,所以我看不出这怎么可能。不过,这暂时有效。 见msdn.microsoft.com/en-us/library/hh404085.aspx(继承章节) 【参考方案1】:

我在尝试扩展 jquery UI 插件时遇到了同样的问题,这是我找到的解决方案(通过 jquery.ui.widget.js 找到的):

(函数($) /** * 命名空间:插件所在的命名空间 * pluginName:插件的名称 */ var extensionMethods = /* * 获取元素的id * 这是现有插件中的一些上下文 */ 显示ID:函数() 返回 this.element[0].id; ; $.extend(true, $[ 命名空间 ][ pluginName ].prototype, extensionMethods); )(jQuery);

希望对您有所帮助,如有任何问题,请询问。

【讨论】:

所以澄清一下,如果我想扩展 jQuery UI 的自动完成功能,那么 Namespace 将是“ui”而 pluginName 将是“自动完成”? 我想我已经回答了我自己的问题。我在它调用jQuery.widget("ui.autocomplete", ...)的自动完成源中找到,在它在“。”处拆分的小部件源中找到,命名空间为索引0,pluginName为索引1。换句话说,看起来我是对的. :) @Jared - 我最终在这里采纳了您的建议来扩展 jQuery UI 自动完成功能。我在这里描述了我的目标:matthuggins.com/articles/…,我在这里有完整的代码:github.com/mhuggins/jquery-ui-autocomplete-hints。如果您有任何改进建议,我很乐意听取他们的意见! 如何找到 Namespace 和 pluginName?【参考方案2】:

我遇到了同样的问题并来到这里,然后 Jared Scott 的回答启发了我。

(function($) 

    var fullCalendarOrg = $.fn.fullCalendar;

    $.fn.fullCalendar = function(options) 
        if(typeof options === "object") 
            options = $.extend(true, options, 
                // locale
                isRTL: false,
                firstDay: 1,
                // some more options
            );
        

        var args = Array.prototype.slice.call(arguments,0);
        return fullCalendarOrg.apply(this, args);
    

)(jQuery);

【讨论】:

【参考方案3】:

我发现很多插件的方法是受保护的/私有的(即在闭包范围内)。如果您需要修改方法/函数的功能,那么除非您愿意分叉,否则您将不走运。现在,如果您不需要更改任何这些方法/功能,那么您可以使用$.extend($.fn.pluginName, /*your methods/properties*/;

我之前最终做的另一件事是简单地将插件用作我的插件的属性,而不是尝试扩展它。

真正归结为您要扩展的插件的编码方式。

【讨论】:

在主扩展中是我想做的所有事情,但在某些情况下,它就像在插件内部创建的 DOM 元素上添加事件处理程序。在其他情况下,我需要覆盖现有方法中的行为。我读的越多,我看到的干净方法就越少。还有其他想法吗? 好吧,如果这些方法是公共 API 中的方法(它们似乎不是),那么您可以使用我上面提到的方法来替换函数定义。除此之外,没有干净的方法。您只需将其分叉以供您使用并破解。 @prodigitalson public* API ;)【参考方案4】:
$.fn.APluginName=function(param1,param2)

  return this.each(function()
    
      //access element like 
      // var elm=$(this);
    );


// sample plugin
$.fn.DoubleWidth=function()
  
    return this.each(function()
      
        var _doublWidth=$(this).width() * 2;
        $(this).width(_doubleWidth);
      );
  

//

<div style="width:200px" id='div!'>some text</div>

// 使用自定义插件

$('#div1').DoubleWidth();

/// 上面写的 utils 类型通常是 dom 元素的工作 /////////////// 自定义工具

(function($)
  var _someLocalVar;
  $.Afunction=function(param1,param2) 
    // do something
  
)(jquery);

//访问上面的util as

$.Afunction();

//这种类型的utils通常扩展javascript

【讨论】:

这不是他要问的——他问的是如何最好地扩展已经存在的插件,以允许更新他用作基础的底层插件,同时在其之上添加他想要的功能。 【参考方案5】:

我重写 jQuery 插件的方法是将需要访问的方法和变量移动到选项块并调用“扩展”

// in the plugin js file
$.jCal = function (target, opt) 
    opt = $.extend(
       someFunctionWeWantToExpose: function() 
           // 'this' refers to 'opt', which is where are our required members can be found
       
    

    // do all sorts of things here to initialize

    return opt; // the plugin initialisation returns an extended options object



////// elsewhere /////

var calendar = $("#cal1").jCal();
calendar.someFunctionWeWantToExpose();

【讨论】:

【参考方案6】:

示例类似于 Jared Scott 的回答,但制作原始对象原型的副本可以调用父方法:

(function($) 

    var original = $.extend(true, , $.cg.combogrid.prototype);

    var extension = 
        _renderHeader: function(ul, colModel) 
            original._renderHeader.apply(this, arguments);

            //do something else here...
        
    ;

    $.extend(true, $.cg.combogrid.prototype, extension);

)(jQuery);

【讨论】:

【参考方案7】:

jQuery Widget 可以使用 jQuery Widget Factory 进行扩展。

(function ($) 
    "use strict";

    define([
        "jquery",
        "widget"
    ], function ($, widget) 
        $.widget("custom.yourWidget", $.fn.fullCalendar, 
            yourFunction: function () 
                // your code here
            
        );

        return $.custom.yourWidget;
    );
(jQuery));

查看 jQuery 文档以了解更多信息:Widget Factory APIExtending Widgets with the Widget Factory

【讨论】:

以上是关于扩展 jQuery 插件的最佳方式的主要内容,如果未能解决你的问题,请参考以下文章

jQuery $.fn.extend方式自定义插件

jquery函数的2种方式定义,扩展extend函数调用

jQuery插件扩展方法

jQuery的noConflict以及插件扩展

jQuery就地编辑插件。可通过插件架构进行扩展。插件的插件。真正地

jQueryjquery插件封装