jQuery插件命名空间函数

时间:2009-08-02 19:35:49

标签: javascript jquery jquery-plugins

我正在创建一个范围相当大的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对象。

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

-Matt

4 个答案:

答案 0 :(得分:11)

只要您使用$.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);
}

答案 1 :(得分: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();
当然,正如开发组帖子中所解释的那样,当然还有许多其他可能性。

答案 2 :(得分:1)

嗯,我相信有很多方法可以给这只猫皮肤。 jQuery UI库使用如下模式:

// initialize a dialog window from an element:
$('#selector').dialog({});

// call the show method of a dialog:
$('#selector').dialog('show');

答案 3 :(得分:0)

我喜欢我在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);