jQuery 插件模板 - 最佳实践、约定、性能和内存影响

     2023-02-22     145

关键词:

【中文标题】jQuery 插件模板 - 最佳实践、约定、性能和内存影响【英文标题】:jQuery plugin template - best practice, convention, performance and memory impact 【发布时间】:2011-08-24 05:23:17 【问题描述】:

我已经开始编写一些 jQuery 插件,并认为使用 jQuery 插件模板设置我的 IDE 会很好。

我一直在阅读该网站上与插件约定、设计等相关的一些文章和帖子。我想我会尝试整合所有这些。

下面是我的模板,我希望经常使用它,所以很想确保它总体上符合 jQuery 插件设计约定,以及拥有多个内部方法(甚至是其通用设计)的想法是否会影响性能并且容易发生内存问题。

(function($)

    var PLUGIN_NAME = "myPlugin"; // TODO: Plugin name goes here.
    var DEFAULT_OPTIONS =
    
        // TODO: Default options for plugin.
    ;
    var pluginInstanceIdCount = 0;

    var I = function(/*HTMLElement*/ element)
    
        return new Internal(element);
    ;

    var Internal = function(/*HTMLElement*/ element)
    
        this.$elem = $(element);
        this.elem = element;
        this.data = this.getData();

        // Shorthand accessors to data entries:
        this.id = this.data.id;
        this.options = this.data.options;
    ;

    /**
     * Initialises the plugin.
     */
    Internal.prototype.init = function(/*Object*/ customOptions)
    
        var data = this.getData();

        if (!data.initialised)
        
            data.initialised = true;
            data.options = $.extend(DEFAULT_OPTIONS, customOptions);

            // TODO: Set default data plugin variables.
            // TODO: Call custom internal methods to intialise your plugin.
        
    ;

    /**
     * Returns the data for relevant for this plugin
     * while also setting the ID for this plugin instance
     * if this is a new instance.
     */
    Internal.prototype.getData = function()
    
        if (!this.$elem.data(PLUGIN_NAME))
        
            this.$elem.data(PLUGIN_NAME, 
                id : pluginInstanceIdCount++,
                initialised : false
            );
        

        return this.$elem.data(PLUGIN_NAME);
    ;

    // TODO: Add additional internal methods here, e.g. Internal.prototype.<myPrivMethod> = function()...

    /**
     * Returns the event namespace for this widget.
     * The returned namespace is unique for this widget
     * since it could bind listeners to other elements
     * on the page or the window.
     */
    Internal.prototype.getEventNs = function(/*boolean*/ includeDot)
    
        return (includeDot !== false ? "." : "") + PLUGIN_NAME + "_" + this.id;
    ;

    /**
     * Removes all event listeners, data and
     * HTML elements automatically created.
     */
    Internal.prototype.destroy = function()
    
        this.$elem.unbind(this.getEventNs());
        this.$elem.removeData(PLUGIN_NAME);

        // TODO: Unbind listeners attached to other elements of the page and window.
    ;

    var publicMethods =
    
        init : function(/*Object*/ customOptions)
        
            return this.each(function()
            
                I(this).init(customOptions);
            );
        ,

        destroy : function()
        
            return this.each(function()
            
                I(this).destroy();
            );
        

        // TODO: Add additional public methods here.
    ;

    $.fn[PLUGIN_NAME] = function(/*String|Object*/ methodOrOptions)
    
        if (!methodOrOptions || typeof methodOrOptions == "object")
        
            return publicMethods.init.call(this, methodOrOptions);
        
        else if (publicMethods[methodOrOptions])
        
            var args = Array.prototype.slice.call(arguments, 1);

            return publicMethods[methodOrOptions].apply(this, args);
        
        else
        
            $.error("Method '" + methodOrOptions + "' doesn't exist for " + PLUGIN_NAME + " plugin");
        
    ;
)(jQuery);

提前致谢。

【问题讨论】:

个人觉得这样的模板真的被过度设计了。我真的不认为你的 JavaScript 需要这么多的混乱。感觉 far 太企业化了。亲吻。 感觉也太 C# / Java ish。不是很 JavaScript 式的。我可能会尝试提供不同的模板。 @Raynos 这是 jQuery 插件中使用的许多技术的组合,也是我见过的最好的通用实现之一。深入研究任何 jQuery 插件,你会看到他在做什么的一个子集。所以大家都做错了吗?我唯一不喜欢的是内部对象名称,我个人会通过在 VS 中将其设为 sn-p 来替换它。我不太懂你的enterprisy/​​c#/java 牛肉。 我从来没有写过 jQuery 插件,但是当我踏上这段旅程时,我会留意这个。 您需要在每行的末尾放置大括号(即 k&r 样式)。因为在 javascript 中,由于分号是可选的,它可能会破坏您的代码。请参阅 codeproject.com/KB/scripting/javascript-gotchas.aspx#semicolons 和 encosia.com/…。 (我知道,我也是一个花括号换新线的人。) 【参考方案1】:

[编辑] 7 个月后

引用自 github 项目

jQuery不行,jQuery插件也不怎么模块化代码。

说真的,“jQuery 插件”不是一个合理的架构策略。编写硬依赖 jQuery 的代码也很愚蠢。

[原创]

由于我对这个模板提出了批评,我将提出一个替代方案。

为了让生活更轻松,这依赖于 jQuery 1.6+ 和 ES5(使用 ES5 Shim)。

我花了一些时间重新设计您提供的插件模板并推出了我自己的。

链接:

Github Documentation Unit tests 已确认通过 FF4、Chrome 和 IE9(IE8 和 OP11 死机。已知 bug)。 Annotated Source Code The PlaceKitten example plugin

比较:

我对模板进行了重构,使其分为样板代码 (85%) 和脚手架代码 (15%)。目的是您只需要编辑脚手架代码,就可以保持样板代码不变。为此,我使用了

继承 var self = Object.create(Base) 而不是直接编辑Internal 类,你应该编辑一个子类。您的所有模板/默认功能都应该在一个基类中(在我的代码中称为Base)。 convention self[PLUGIN_NAME] = main; 按照惯例,jQuery 上定义的插件默认会调用self[PLUGIN_NAME] 上定义的方法。这被认为是main 插件方法,为了清楚起见,它有一个单独的外部方法。 monkey patching $.fn.bind = function _bind ... 使用monkey patching 意味着事件命名空间会在后台自动为您完成。此功能是免费的,不会以牺牲可读性为代价(始终调用getEventNS)。

OO 技术

最好坚持正确的 JavaScript OO 而不是经典的 OO 仿真。为此,您应该使用Object.create。 (ES5 只是使用 shim 来升级旧浏览器)。

var Base = (function _Base() 
    var self = Object.create(); 
    /* ... */
    return self;
)();

var Wrap = (function _Wrap() 
    var self = Object.create(Base);
    /* ...  */
    return self;
)();

var w = Object.create(Wrap);

这与人们习惯的基于标准new.prototype 的OO 不同。这种方法是首选,因为它再次强化了 JavaScript 中只有对象的概念,并且它是一种典型的 OO 方法。

[getEventNs]

如前所述,此方法已通过重写 .bind.unbind 进行重构,以自动注入命名空间。这些方法在 jQuery $.sub() 的私有版本上被覆盖。被覆盖的方法与命名空间的行为方式相同。它根据插件和围绕 HTMLElement 的插件包装器实例来唯一地命名事件(使用 .ns

[getData]

此方法已替换为具有与jQuery.fn.data 相同 API 的 .data 方法。它是相同的 API 的事实使它更易于使用,它基本上是一个带有命名空间的 jQuery.fn.data 的薄包装。这允许您设置仅为该插件立即存储的键/值对数据。多个插件可以并行使用此方法而不会发生任何冲突。

[publicMethods]

publicMethods 对象已被 Wrap 上定义的任何方法替换为自动公开。您可以直接在 Wrapped 对象上调用任何方法,但您实际上无权访问 Wrapped 对象。

[$.fn[PLUGIN_NAME]]

这已被重构,因此它公开了更标准化的 API。这个api是

$(selector).PLUGIN_NAME("methodName", /* object hash */); // OR
$(selector).PLUGIN_NAME(/* object hash */); // methodName defaults to PLUGIN_NAME

选择器中的元素会自动包装在Wrap 对象中,调用该方法或选择器中的每个选定元素,并且返回值始终是$.Deferred 元素。

这标准化了 API 和返回类型。然后,您可以在返回的 deferred 上调用 .then 以获取您关心的实际数据。无论插件是同步的还是异步的,这里使用 deferred 都非常强大。

_create

添加了缓存创建功能。这被称为将 HTMLElement 转换为 Wrapped 元素,并且每个 HTMLElement 只会被包装一次。这种缓存可以显着减少内存。

$.PLUGIN_NAME

为插件添加了另一个公共方法(一共两个!)。

$.PLUGIN_NAME(elem, "methodName", /* options */);
$.PLUGIN_NAME([elem, elem2, ...], "methodName", /* options */);
$.PLUGIN_NAME("methodName",  
  elem: elem, /* [elem, elem2, ...] */
  cb: function()  /* success callback */ 
  /* further options */
);

所有参数都是可选的。 elem 默认为&lt;body&gt;"methodName" 默认为"PLUGIN_NAME"/* options */ 默认为

这个 API 非常灵活(有 14 种方法重载!)并且标准足以让您习惯插件将公开的每个方法的语法。

Public exposure

Wrapcreate$ 对象在全局范围内公开。这将允许高级插件用户使用您的插件获得最大的灵活性。他们可以在他们的开发中使用create 和修改后的subbed $,他们也可以猴子补丁Wrap。这允许即挂钩到您的插件方法。所有这三个都在其名称前标有_,因此它们是内部的,使用它们会破坏您的插件工作的保证。

内部defaults 对象也公开为$.PLUGIN_NAME.global。这允许用户覆盖您的默认值并设置插件全局defaults。在这个插件设置中,作为对象的所有哈希都与默认值合并,因此这允许用户为所有方法设置全局默认值。

Actual Code

(function($, jQuery, window, document, undefined) 
    var PLUGIN_NAME = "Identity";
    // default options hash.
    var defaults = 
        // TODO: Add defaults
    ;

    // -------------------------------
    // -------- BOILERPLATE ----------
    // -------------------------------

    var toString = Object.prototype.toString,
        // uid for elements
        uuid = 0,
        Wrap, Base, create, main;

    (function _boilerplate() 
        // over-ride bind so it uses a namespace by default
        // namespace is PLUGIN_NAME_<uid>
        $.fn.bind = function  _bind(type, data, fn, nsKey) 
            if (typeof type === "object") 
                for (var key in type) 
                    nsKey = key + this.data(PLUGIN_NAME)._ns;
                    this.bind(nsKey, data, type[key], fn);
                
                return this;
            

            nsKey = type + this.data(PLUGIN_NAME)._ns;
            return jQuery.fn.bind.call(this, nsKey, data, fn);
        ;

        // override unbind so it uses a namespace by default.
        // add new override. .unbind() with 0 arguments unbinds all methods
        // for that element for this plugin. i.e. calls .unbind(_ns)
        $.fn.unbind = function _unbind(type, fn, nsKey) 
            // Handle object literals
            if ( typeof type === "object" && !type.preventDefault ) 
                for ( var key in type ) 
                    nsKey = key + this.data(PLUGIN_NAME)._ns;
                    this.unbind(nsKey, type[key]);
                
             else if (arguments.length === 0) 
                return jQuery.fn.unbind.call(this, this.data(PLUGIN_NAME)._ns);
             else 
                nsKey = type + this.data(PLUGIN_NAME)._ns;
                return jQuery.fn.unbind.call(this, nsKey, fn);    
            
            return this;
        ;

        // Creates a new Wrapped element. This is cached. One wrapped element 
        // per HTMLElement. Uses data-PLUGIN_NAME-cache as key and 
        // creates one if not exists.
        create = (function _cache_create() 
            function _factory(elem) 
                return Object.create(Wrap, 
                    "elem": value: elem,
                    "$elem": value: $(elem),
                    "uid": value: ++uuid
                );
            
            var uid = 0;
            var cache = ;

            return function _cache(elem) 
                var key = "";
                for (var k in cache) 
                    if (cache[k].elem == elem) 
                        key = k;
                        break;
                    
                
                if (key === "") 
                    cache[PLUGIN_NAME + "_" + ++uid] = _factory(elem);
                    key = PLUGIN_NAME + "_" + uid;
                 
                return cache[key]._init();
            ;
        ());

        // Base object which every Wrap inherits from
        Base = (function _Base() 
            var self = Object.create();
            // destroy method. unbinds, removes data
            self.destroy = function _destroy() 
                if (this._alive) 
                    this.$elem.unbind();
                    this.$elem.removeData(PLUGIN_NAME);
                    this._alive = false;    
                
            ;

            // initializes the namespace and stores it on the elem.
            self._init = function _init() 
                if (!this._alive) 
                    this._ns = "." + PLUGIN_NAME + "_" + this.uid;
                    this.data("_ns", this._ns);    
                    this._alive = true;
                
                return this;
            ;

            // returns data thats stored on the elem under the plugin.
            self.data = function _data(name, value) 
                var $elem = this.$elem, data;
                if (name === undefined) 
                    return $elem.data(PLUGIN_NAME);
                 else if (typeof name === "object") 
                    data = $elem.data(PLUGIN_NAME) || ;
                    for (var k in name) 
                        data[k] = name[k];
                    
                    $elem.data(PLUGIN_NAME, data);
                 else if (arguments.length === 1) 
                    return ($elem.data(PLUGIN_NAME) || )[name];
                 else  
                    data = $elem.data(PLUGIN_NAME) || ;
                    data[name] = value;
                    $elem.data(PLUGIN_NAME, data);
                
            ;
                return self;
        )();

        // Call methods directly. $.PLUGIN_NAME(elem, "method", option_hash)
        var methods = jQuery[PLUGIN_NAME] = function _methods(elem, op, hash) 
            if (typeof elem === "string") 
                hash = op || ;
                op = elem;
                elem = hash.elem;
             else if ((elem && elem.nodeType) || Array.isArray(elem)) 
                if (typeof op !== "string") 
                    hash = op;
                    op = null;
                
             else 
                hash = elem || ;
                elem = hash.elem;
            

            hash = hash || 
            op = op || PLUGIN_NAME;
            elem = elem || document.body;
            if (Array.isArray(elem)) 
                var defs = elem.map(function(val) 
                    return create(val)[op](hash);    
                );
             else 
                var defs = [create(elem)[op](hash)];    
            

            return $.when.apply($, defs).then(hash.cb);
        ;

        // expose publicly.
        Object.defineProperties(methods, 
            "_Wrap": 
                "get": function()  return Wrap; ,
                "set": function(v)  Wrap = v; 
            ,
            "_create":
                value: create
            ,
            "_$": 
                value: $    
            ,
            "global": 
                "get": function()  return defaults; ,
                "set": function(v)  defaults = v; 
             
        );

        // main plugin. $(selector).PLUGIN_NAME("method", option_hash)
        jQuery.fn[PLUGIN_NAME] = function _main(op, hash) 
            if (typeof op === "object" || !op) 
                hash = op;
                op = null;
            
            op = op || PLUGIN_NAME;
            hash = hash || ;

            // map the elements to deferreds.
            var defs = this.map(function _map() 
                return create(this)[op](hash);
            ).toArray();

            // call the cb when were done and return the deffered.
            return $.when.apply($, defs).then(hash.cb);

        ;
    ());

    // -------------------------------
    // --------- YOUR CODE -----------
    // -------------------------------

    main = function _main(options) 
        this.options = options = $.extend(true, defaults, options); 
        var def = $.Deferred();

        // Identity returns this & the $elem.
        // TODO: Replace with custom logic
        def.resolve([this, this.elem]);

        return def;
    

    Wrap = (function() 
        var self = Object.create(Base);

        var $destroy = self.destroy;
        self.destroy = function _destroy() 
            delete this.options;
            // custom destruction logic
            // remove elements and other events / data not stored on .$elem

            $destroy.apply(this, arguments);
        ;

        // set the main PLUGIN_NAME method to be main.
        self[PLUGIN_NAME] = main;

        // TODO: Add custom logic for public methods

        return self;
    ());

)(jQuery.sub(), jQuery, this, document);

可以看出,您应该编辑的代码位于YOUR CODE 行的下方。 Wrap 对象的行为类似于您的 Internal 对象。

函数main是用$.PLUGIN_NAME()$(selector).PLUGIN_NAME()调用的主函数,应该包含你的主逻辑。

【讨论】:

我承认我没有仔细分析您的答案,但有一个问题似乎真的很重要:您的代码是否“沙盒”足以被多次调用以使其可以应用它到单个页面上的多个元素?换句话说:如果我在div 上初始化这样的插件@ 没有。 1,是否可以在div no. 上无缝应用它。 2?只是问一下,因为您可能知道,而且我认为这个问题非常重要。 什么是 ES5?如果您正在阅读此答案,您可能不知道它是 ECMAScript 标准的第 5 版:en.wikipedia.org/wiki/ECMAScript#Versions @Raynos ,我正在尝试学习 jQuery 插件开发(以及同时学习 OO JavaScript)。对于想要将其用于学习和生产的初学者(包括 .min.js),您如何看待让您的代码更具可读性。例如,使用main plugin,您可能会非常(不必要地)冗长?即将参数 op 重命名为 operation_to_call ,可能包括第 180 行的 else 条件的注释描述。 cbcallback_function,对吧? @BrianL 我是两个月前写的。如果我要触摸它,我会完全重写它。实际上,这些天我建议不要使用 jQuery 句号,但那是另一回事。但是,如果您想讨论模块化 JS 开发,请随时 Chat with us @Raynos jQuery 插件很棒,告诉我为什么它们不是?我在我构建的任何站点中都包含 jQuery,API、选择器支持、简化常见任务的简单程序是无与伦比的,所以因为我和大多数人总是有这种依赖关系,为什么不制作 jQuery 插件来模块化组件呢?例如,如果我要制作一个自动完成系统并使其可重用,你为什么不建议将其制作为 jQuery 插件,你还会使用 jQuery 让生活更轻松吗?【参考方案2】:

不久前,我根据我读过的一篇博客文章构建了一个插件生成器:http://jsfiddle.net/KeesCBakker/QkPBF/。它可能有用。这是相当基本和直接的。任何 cmets 都将受到欢迎。

您可以创建自己的生成器并根据需要进行更改。

附言。这是生成的主体:

(function($)

    //My description
    function MyPluginClassName(el, options) 

        //Defaults:
        this.defaults = 
            defaultStringSetting: 'Hello World',
            defaultIntSetting: 1
        ;

        //Extending options:
        this.opts = $.extend(, this.defaults, options);

        //Privates:
        this.$el = $(el);
    

    // Separate functionality from object creation
    MyPluginClassName.prototype = 

        init: function() 
            var _this = this;
        ,

        //My method description
        myMethod: function() 
            var _this = this;
        
    ;

    // The actual plugin
    $.fn.myPluginClassName = function(options) 
        if(this.length) 
            this.each(function() 
                var rev = new MyPluginClassName(this, options);
                rev.init();
                $(this).data('myPluginClassName', rev);
            );
        
    ;
)(jQuery);

【讨论】:

我觉得生成插件的代码不是插件很有趣。 我真的很喜欢 jsFiddle 的这种用法。但是 TODO 什么时候完成呢? ;) @ErickPetru 不知道,大多数时候我用它来为我的课程制作基本骨架,实际上并不需要实际验证。 代码是否使用了 Raynos 的回答所做的所有最佳实践和现代化?拥有一个生成器和最先进的脚手架/代码库会很棒。 美丽。简单而优雅。正是我开始正确的插件开发所需要的。【参考方案3】:

我一直在谷歌搜索并登陆这里,所以我必须发表一些想法:首先我同意@Raynos。

大多数尝试构建 jQuery 插件的代码实际上...不是插件!它只是一个存储在内存中的对象,由节点/元素的数据属性引用。这是因为 jQuery 应该被视为和类库一起使用的工具(以弥补 OO 架构中 js 的不一致性),以构建更好的代码,是的,这一点都不错!

如果您不喜欢经典的 OO 行为,请坚持使用 clone 之类的原型库。

那么我们真正的选择是什么?

使用 JQueryUI/Widget 或类似的库来隐藏技术细节和 提供抽象 不要因为复杂、学习曲线和天知道未来的变化而使用它们 不要使用它们,因为你要坚持模块化设计,以后再做小增量 不要使用它们,因为您可能希望将代码移植/连接到不同的库。

假设以下场景解决的问题(请参阅此问题的复杂性:Which jQuery plugin design pattern should I use?):

我们有节点 A、B 和 C,它们将对象引用存储到它们的 data 属性中

其中一些将信息存储在公共私有可访问内部对象中, 这些对象的某些类与继承相关联, 所有这些节点还需要一些私有公共单例才能发挥最佳作用。

我们会怎么做?看图:

classes : |  A        B         C
------------------case 1----------
members   |  |        |         |
  of      |  v        v         v
an object | var a=new A, b=new B,  c=new C
  at      |     B extends A
node X :  |  a, b, c : private
------------------case 2---------
members   |  |        |         |
  of      |  v        v         v
an object | var aa=new A, bb=new B, cc=new C
  at      |     BB extends AA
node Y :  |  aa, bb, cc : public
-------------------case 3--------
members   |  |        |         |
  of      |  v        v         v
an object | var d= D.getInstance() (private),
  at      |     e= E.getInstance() (public)
node Z :  |     D, E : Singletons

你可以看到每个节点都指向一个对象——一种 jQuery 方法——但是这些对象变化很大;它们包含存储在不同数据中的对象属性,或者甚至应该是......在内存中单一的单例,就像对象的原型函数一样。我们不希望属于class A 的每个对象的函数都在每个节点的对象中重复在内存中复制

在我回答之前看看我在 jQuery 插件中看到的一种常见方法 - 其中一些非常流行,但我不说名字:

(function($, window, document, undefined)
   var x = '...', y = '...', z = '...',
       container, $container, options;
   var myPlugin = (function() //<----the game is lost!
      var defaults = 

      ;
      function init(elem, options) 
         container = elem;
         $container = $(elem);
         options = $.extend(, defaults, options);
      
      return 
         pluginName: 'superPlugin',
         init: function(elem, options) 
            init(elem, options);
         
      ;
   )();
   //extend jquery
   $.fn.superPlugin = function(options) 
      return this.each(function() 
         var obj = Object.create(myPlugin); //<---lose, lose, lose!
         obj.init(this, options);
         $(this).data(obj.pluginName, obj);
      );
   ;

(jQuery, window, document));

我正在观看 Ben Alman 的 http://www.slideshare.net/benalman/jquery-plugin-creation 的一些幻灯片,他在幻灯片 13 中将 object literals 称为 singletons 这简直让我大吃一惊:这就是上面的插件所做的,它创建了一个单例,没有机会来改变它的内部状态!!!

此外,在 jQuery 部分,它存储了每个节点的公共引用

我的解决方案使用 factory 来保持内部状态并返回一个对象,并且可以使用 class 扩展它strong> 库并拆分为不同的文件:

;(function($, window, document, undefined)
   var myPluginFactory = function(elem, options)
   ........
   var modelState = 
      options: null //collects data from user + default
   ;
   ........
   function modeler(elem)
      modelState.options.a = new $$.A(elem.href);
      modelState.options.b = $$.B.getInstance();
   ;
   ........
   return 
         pluginName: 'myPlugin',
         init: function(elem, options) 
            init(elem, options);
         ,
         get_a: function()return modelState.options.a.href;,
         get_b: function()return modelState.options.b.toString();
      ;
   ;
   //extend jquery
   $.fn.myPlugin = function(options) 
      return this.each(function() 
         var plugin = myPluginFactory(this, options);
         $(this).data(plugin.pluginName, plugin);
      );
   ;
(jQuery, window, document));

我的项目:https://github.com/centurianii/jsplugin

见:http://jsfiddle.net/centurianii/s4J2H/1/

【讨论】:

【参考方案4】:

这样的事情怎么样?它更清晰,但如果您可以改进它而不使其过于简单,那么再次收到您的来信会很高兴。

// jQuery plugin Template
(function($)
    $.myPlugin = function(options)  //or use "$.fn.myPlugin" or "$.myPlugin" to call it globaly directly from $.myPlugin();
        var defaults = 
            target: ".box",
            buttons: "li a"             
        ;

        options = $.extend(defaults, options);

        function logic()
            // ... code goes here
        

        //DEFINE WHEN TO RUN THIS PLUGIN
        $(window).on('load resize', function ()  // Load and resize as example ... use whatever you like
            logic();
        );

        // RETURN OBJECT FOR CHAINING
        // return this;

        // OR FOR FOR MULTIPLE OBJECTS
        // return this.each(function() 
        //    // Your code ...
        // );

    ;
)(jQuery);


// USE EXAMPLE with default settings
$.myPlugin(); // or run plugin with default settings like so.

// USE EXAMPLE with overwriten settings
var options = 
    target: "div.box", // define custom options
    buttons: ".something li a" // define custom options
     
$.myPlugin(options); //or run plugin with overwriten default settings

【讨论】:

CSS3 - 性能最佳实践是啥? [关闭]

】CSS3-性能最佳实践是啥?[关闭]【英文标题】:CSS3-Whataretheperformancebestpractices?[closed]CSS3-性能最佳实践是什么?[关闭]【发布时间】:2011-11-2102:38:15【问题描述】:去年我花了很长时间阅读javascript性能、瓶颈和最佳实践。在我的... 查看详情

避免污染 jQuery 命名空间的最佳插件开发实践?

】避免污染jQuery命名空间的最佳插件开发实践?【英文标题】:BestplugindevelopmentpracticestoavoidpollutingjQuerynamespace?【发布时间】:2010-12-2202:02:32【问题描述】:我创建了一个jQuery插件,允许用户与树进行交互(创建、更新、删除节... 查看详情

ObjectMapper - 线程安全和性能的最佳实践

】ObjectMapper-线程安全和性能的最佳实践【英文标题】:ObjectMapper-Bestpracticeforthread-safetyandperformance【发布时间】:2019-12-3109:16:24【问题描述】:总结我想在下面描述的用例上下文中找到在线程安全和性能方面使用ObjectMapper和/或Obj... 查看详情

Perl 中带有输出参数的子例程的最佳实践命名约定

】Perl中带有输出参数的子例程的最佳实践命名约定【英文标题】:BestpracticenamingconventioninPerlforsubroutinewithoutputarguments【发布时间】:2016-06-0819:16:37【问题描述】:简介:我通常不使用输出参数(作为输入和输出值或仅作为输出... 查看详情

C# GUI 命名约定的最佳实践? [关闭]

】C#GUI命名约定的最佳实践?[关闭]【英文标题】:BestpracticesforC#GUInamingconventions?[closed]【发布时间】:2010-11-1719:23:12【问题描述】:无论是用WinForms还是XAML编写的GUI,我所看到的项目之间的命名约定似乎都存在最大差异。对于一... 查看详情

什么是分析和性能测试 python 代码的最佳实践和工具? [复制]

】什么是分析和性能测试python代码的最佳实践和工具?[复制]【英文标题】:Whatsarebestpracticesandtoolsforprofilingandperformancetestingpythoncode?[duplicate]【发布时间】:2012-02-2300:54:26【问题描述】:可能重复:Howtoprofilemycode?什么是分析和性... 查看详情

7个pythonapi最佳实践

动动发财的小手,点个赞吧!本文[1]将介绍7个PythonAPI最佳实践API是软件开动动发财的小手,点个赞吧!本文将介绍7个PythonAPI最佳实践API是软件开发必不可少的工具。它们允许开发人员创建可以与其他系统和服务交互的应用程序... 查看详情

jQuery 标准和最佳实践 [关闭]

】jQuery标准和最佳实践[关闭]【英文标题】:jQueryStandardsandBestPractice[closed]【发布时间】:2010-11-1718:02:38【问题描述】:我目前负责将jQuery的使用推广到我们公司内的Web开发人员社区。其中一部分涉及展示课程,但另一部分涉及... 查看详情

用另一列“扩展”一个 HIVE 查询:性能和最佳实践

】用另一列“扩展”一个HIVE查询:性能和最佳实践【英文标题】:"Extend"aHIVEquerywithanothercolumn:performanceandbestpractices【发布时间】:2019-02-1322:00:57【问题描述】:我有一个HIVE查询,它使用GROUPBY计算一些值。SELECTCOUNT(DISTINCT... 查看详情

一对多关系中的 PHP 和 API 调用性能和最佳实践

】一对多关系中的PHP和API调用性能和最佳实践【英文标题】:PHPandAPIcallsperformanceandbestpracticesinonetomanyrelationship【发布时间】:2017-01-0908:53:36【问题描述】:我们有一个带有电子学习网页的服务器,该网页将数据存储到MySQL数据库... 查看详情

Slick 对 numThreads 和获得良好性能的最佳实践感到困惑

】Slick对numThreads和获得良好性能的最佳实践感到困惑【英文标题】:SlickconfusedaboutnumThreadsandbestpracticeforgoodperformance【发布时间】:2016-09-2612:06:15【问题描述】:我正在使用带有Slick的PlayFrameWork,并在一个I/O数据库繁重的系统中... 查看详情

在 django 模板中包含 javascript 的最佳实践

】在django模板中包含javascript的最佳实践【英文标题】:bestpracticeincludingjavascriptindjangotemplate【发布时间】:2012-04-2701:57:48【问题描述】:以前我曾经在模板中这样做<html>...<script>%include"myapp/includes/jquery-1.7.1.min.js"%%include"m... 查看详情

性能测试最佳实践

...面,将描述软件性能测试过程的关键阶段,以及最佳实践。一、软件性能测试过程的5个 查看详情

使用 jQuery 解析远程内容的最佳实践是啥?

】使用jQuery解析远程内容的最佳实践是啥?【英文标题】:WhatisthebestpracticeforparsingremotecontentwithjQuery?使用jQuery解析远程内容的最佳实践是什么?【发布时间】:2010-11-0507:31:41【问题描述】:在调用jQueryajax来检索整个XHTML文档之... 查看详情

jQuery:取消设置/删除函数事件的最佳实践?

】jQuery:取消设置/删除函数事件的最佳实践?【英文标题】:jQuery:bestpracticeforunsetting/removingfunctionevents?【发布时间】:2011-12-1900:10:36【问题描述】:我正在使用jQuery插件CloudZoom,并且我已经更改了初始化,以便在用户单击“放... 查看详情

实时查询性能

】实时查询性能【英文标题】:livequeryperformance【发布时间】:2011-06-1614:58:30【问题描述】:我最近discovered说jQuery的livequery插件可能非常浪费,因为它不使用事件委托而是绑定所有可绑定事件并在每次更改时重新检查整个DOM如果... 查看详情

js最佳实践

1.可维护性:可理解性:理解意图和一般途径 直观性: 可适应性 可拓展性 可调试性2.代码约定:  1.可读性:缩进与注释。以下地方需要进行注释:    a.函数和方法:描述目的和用于完成任务使用的算法... 查看详情

java性能优化最佳实践,github已标星16k

一、Netty概念及体系结构01Netty——异步和事件驱动Java网络编程NIO选择器Netty的简介、谁在使用Netty、异步和事件驱动Netty的核心组件02你的第一款Netty应用程序获取并安装Java开发下载和安装IDE、ApacheMavenNetty客户端服务器概览编写Ec... 查看详情