久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

jQuery 插件模板 - 最佳實踐、約定、性能和內(nèi)存影

jQuery plugin template - best practice, convention, performance and memory impact(jQuery 插件模板 - 最佳實踐、約定、性能和內(nèi)存影響)
本文介紹了jQuery 插件模板 - 最佳實踐、約定、性能和內(nèi)存影響的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧!

問題描述

我已經(jīng)開始編寫一些 jQuery 插件,并認(rèn)為使用 jQuery 插件模板設(shè)置我的 IDE 會很好.

I've started to write few jQuery plugins and figured it'd be nice to setup my IDE with a jQuery plugin template.

我一直在閱讀本網(wǎng)站上與插件約定、設(shè)計等相關(guān)的一些文章和帖子.我想我會嘗試整合所有這些內(nèi)容.

I have been reading some articles and posts on this site related to plugin convention, design, etc.. and thought I'd try and consolidate all of that.

下面是我的模板,我希望經(jīng)常使用它,所以很想確保它總體上符合 jQuery 插件設(shè)計約定,以及擁有多個內(nèi)部方法(甚至它的一般設(shè)計)的想法是否會影響性能并且容易發(fā)生內(nèi)存問題.

Below is my template, I am looking to use it frequently so was keen to ensure it generally conforms to jQuery plugin design convention and whether the idea of having multiple internal methods (or even its general design) would impact performance and be prone to memory issues.

(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);

提前致謝.

推薦答案

7 個月后

引用自 github 項目

Quoting from the github project

jQuery不行,jQuery插件也不怎么模塊化代碼.

jQuery is no good, and jQuery plugins is not how do modular code.

說真的,jQuery 插件"不是一個合理的架構(gòu)策略.編寫硬依賴 jQuery 的代碼也很愚蠢.

Seriously "jQuery plugins" are not a sound architecture strategy. Writing code with a hard dependency on jQuery is also silly.

[原創(chuàng)]

由于我對這個模板提出了批評,我將提出一個替代方案.

Since I gave critique about this template I will propose an alternative.

為了讓生活更輕松,這依賴于 jQuery 1.6+ 和 ES5(使用 ES5 墊片).

To make live easier this relies on jQuery 1.6+ and ES5 (use the ES5 Shim).

我花了一些時間重新設(shè)計您提供的插件模板并推出了我自己的.

I've spend some time re-designing the plugin template you've given and rolled out my own.

鏈接:

  • Github
  • 文檔
  • 單元測試 確認(rèn)通過FF4、Chrome和IE9(IE8 和 OP11 死機.已知 錯誤).
  • 帶注釋的源代碼
  • PlaceKitten 示例插件
  • Github
  • Documentation
  • Unit tests Confirmed to pass in FF4, Chrome and IE9 (IE8 & OP11 dies. known bug).
  • Annotated Source Code
  • The PlaceKitten example plugin

比較:

我對模板進行了重構(gòu),使其分為樣板代碼 (85%) 和腳手架代碼 (15%).目的是您只需要編輯腳手架代碼,就可以保持樣板代碼不變.為此,我使用了

I've refactored the template so that it's split into boilerplate (85%) and scaffolding code (15%). The intention is that you only have to edit the scaffolding code and you can keep leave boilerplate code untouched. To achieve this I've used

  • 繼承 var self = Object.create(Base) 而不是直接編輯 Internal 類,你應(yīng)該編輯一個子類.您所有的模板/默認(rèn)功能都應(yīng)該在一個基類中(在我的代碼中稱為 Base).
  • 約定 self[PLUGIN_NAME] = main; 按照慣例,jQuery 上定義的插件默認(rèn)會調(diào)用 self[PLUGIN_NAME] 上的方法定義.這被認(rèn)為是 main 插件方法,為了清楚起見,它有一個單獨的外部方法.
  • 猴子補丁 $.fn.bind = function _bind ... 使用猴子補丁意味著事件命名空間會在后臺自動為您完成.此功能是免費的,不會以可讀性為代價(一直調(diào)用 getEventNS).
  • inheritance var self = Object.create(Base) Rather then editing the Internal class you have directly you should be editing a sub class. All your template / default functionality should be in a base class (called Base in my code).
  • convention self[PLUGIN_NAME] = main; By convention the plugin defined on jQuery will call the method define on self[PLUGIN_NAME] by default. This is considered the main plugin method and has a seperate external method for clarity.
  • monkey patching $.fn.bind = function _bind ... Use of monkey patching means that the event namespacing is done automatically for you under the hood. This functionality is free and does not come at the cost of readability (calling getEventNS all the time).

OO 技術(shù)

最好堅持正確的 JavaScript OO 而不是經(jīng)典的 OO 仿真.為此,您應(yīng)該使用 Object.create.(ES5 只是使用 shim 來升級舊瀏覽器).

It's better to stick to proper JavaScript OO rather then classical OO emulation. To achieve this you should use Object.create. (which ES5 just use the shim to upgrade old browsers).

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);

這不同于人們習(xí)慣的基于標(biāo)準(zhǔn)new.prototype的OO.這種方法是首選,因為它再次強化了 JavaScript 中只有對象的概念,并且它是一種典型的 OO 方法.

This is different from the standard new and .prototype based OO people are used to. This approach is preferred because it re-inforces the concept that there are only Objects in JavaScript and it's a prototypical OO approach.

[getEventNs]

如前所述,此方法已通過重寫 .bind.unbind 進行重構(gòu),以自動注入命名空間.這些方法在 jQuery 的私有版本上被覆蓋 $.sub().被覆蓋的方法與命名空間的行為方式相同.它基于插件和圍繞 HTMLElement 的插件包裝器實例唯一地命名事件(使用 .ns.

As mentioned this method has been refactored away by overriding .bind and .unbind to automatically inject namespaces. These methods are overwritten on the private version of jQuery $.sub(). The overwritten methods behave the same way as your namespacing does. It namespaces events uniquely based on plugin and instance of a plugin wrapper around a HTMLElement (Using .ns.

[getData]

此方法已替換為 .data 方法與 jQuery.fn.data 具有相同的 API.它是相同的 API 的事實使它更易于使用,它基本上是一個帶有命名空間的 jQuery.fn.data 的薄包裝.這允許您設(shè)置僅為該插件立即存儲的鍵/值對數(shù)據(jù).多個插件可以并行使用此方法而不會發(fā)生任何沖突.

This method has been replaced with a .data method that has the same API as jQuery.fn.data. The fact that it's the same API makes it easier to use, its basically a thin wrapper around jQuery.fn.data with namespacing. This allows you to set key/value pair data that is immediatley stored for that plugin only. Multiple plugins can use this method in parallel without any conflicts.

[publicMethods]

publicMethods 對象已被在 Wrap 上定義的任何方法替換為自動公開.您可以直接在 Wrapped 對象上調(diào)用任何方法,但您實際上無權(quán)訪問 Wrapped 對象.

The publicMethods object has been replaced by any method being defined on Wrap being automatically public. You can call any method on a Wrapped object directly but you do not actually have access to the wrapped object.

[$.fn[PLUGIN_NAME]]

這已被重構(gòu),因此它公開了更標(biāo)準(zhǔn)化的 API.這個api是

This has been refactored so it exposes a more standardized API. This api is

$(selector).PLUGIN_NAME("methodName", {/* object hash *
                
【網(wǎng)站聲明】本站部分內(nèi)容來源于互聯(lián)網(wǎng),旨在幫助大家更快的解決問題,如果有圖片或者內(nèi)容侵犯了您的權(quán)益,請聯(lián)系我們刪除處理,感謝您的支持!

相關(guān)文檔推薦

jQuery/JavaScript Library for avatar creation?(用于創(chuàng)建頭像的 jQuery/JavaScript 庫?)
How to do following mask input problem?(如何做以下掩碼輸入問題?)
Issues Setting Value/Label Using DropKick Javascript(使用 DropKick Javascript 設(shè)置值/標(biāo)簽的問題)
how to unit-test private methods in jquery plugins?(如何對 jquery 插件中的私有方法進行單元測試?)
stellar.js - configuring offsets / aligning elements for a vertical scrolling website?(stellar.js - 為垂直滾動網(wǎng)站配置偏移量/對齊元素?)
jQuery masked input plugin. select all content when textbox receives focus(jQuery 屏蔽輸入插件.當(dāng)文本框獲得焦點時選擇所有內(nèi)容)
主站蜘蛛池模板: 激情五月综合 | jlzzxxxx18hd护士| 欧美在线观看免费观看视频 | 国产美女精品 | 在线精品一区二区 | 天堂一区二区三区四区 | 亚洲午夜电影 | 亚洲精品视频一区二区三区 | 日韩视频在线播放 | 日韩1区2区| 精品久久久久久亚洲综合网 | 欧美在线观看一区二区 | 久久久九九九九 | 一区二区三区在线 | 欧 | 美美女高清毛片视频免费观看 | 成人日韩精品 | 日韩精品一区二区三区免费视频 | 亚洲国产成人av好男人在线观看 | 91精品91久久久 | 久久一区精品 | 日韩免费在线观看视频 | 午夜精品视频 | 一本综合久久 | 亚洲成人中文字幕 | 成人免费在线观看 | 精品国产乱码久久久久久闺蜜 | 7777奇米影视| 亚洲一区二区精品视频 | 日本精品网站 | 久久av.com | 色精品| 久久国产精品一区二区三区 | 久久久久久亚洲精品 | 午夜精品视频 | www.色婷婷 | 精品久久久久久亚洲精品 | 久久激情视频 | 999久久久久久久 | 亚洲 中文 欧美 日韩 在线观看 | xxxxx黄色片| 国产小视频在线观看 |