如何使用NameSpace创建jQuery元素方法



只需说一句,我想对我的插件进行一点分支编写,并决定能够"命名"它们。到目前为止,将$.method重写为$.namespace.method是很容易的。

我遇到的问题是制作元素方法,如$('element').method(),但要使用名称空间;例如CCD_ 4。我已经尝试了一些变通方法,可以创建$.fn.namespace.method,但是,当我从该方法中调用this时,我只得到$.fn.namespace,而不是我想要得到的'element'

示例:如果我调用$('body').namespace.test(),那么在方法test中,我希望this是元素<body></body>

任何想办法实现这一目标的帮助都将不胜感激。可能只是像往常一样过度思考。

目前正在尝试类似$('body').namespace().method()的可能解决方案,到目前为止,效果不太好…:P

如果不需要与IE8兼容,可以使用Object.defineProperty.

工作示例:

 Object.defineProperty($.fn, 'namespace', {
  get: function(){
    var t = this;
    return {
      lowercasehtml: function(){
         return t.html(function(_,h){ return h.toLowerCase() }); 
      }
    }
  }
});
$('#a').namespace.lowercasehtml(); // changes the html of #a to lowercase (yes, it's stupid, I know)

演示

但我不相信这样命名名称空间是个好主意。我会简单地定义

$.fn.namespace_lowercasehtml = function() ...

这就是我个人为jQuery的应用程序特定扩展所做的。

虽然我不建议这样做,但您可以为每次调用namespace():生成一个新对象

(function($){
    var plugin = {
        test: function (){
            console.log(this);
        }
    };
    var methods = Object.keys( plugin );
    $.fn.namespace = function (){
        var self = this,
            localMethods = {};
        $.each(methods, function () {
            localMethods[ this ] = plugin[ this ].bind(self);
        });
        return localMethods;
    };
}(jQuery));

小提琴在这儿:http://jsfiddle.net/WaXzL/


您可以为较旧的浏览器polyfill Object.keys,也可以手动创建methods数组。

bind也是如此:要么用polyfill填充,要么用call手动填充。

以下是一个可以在旧浏览器中工作的版本:

(function($){
    var plugin = {
        test: function (){
            console.log(this);
        }
    };
    var methods = [];
    for ( var i in plugin ) {
        if ( plugin.hasOwnProperty(i) ) {
            methods.push(i);
        }
    }
    $.fn.namespace = function (){
        var self = this,
            localMethods = {};
        $.each(methods, function (i, method) {
            localMethods[ method ] = function () {
                plugin[ method ].call( self );
            };
        });
        return localMethods;
    };
}(jQuery));

这是小提琴:http://jsfiddle.net/WaXzL/1/

不如做:

$('element').namespace.method()

你可以简化它并进行

$('element').namespace('method')

相反?这要简单得多:

(function($){
    var methods = {
        test: function(a, b){
            console.log(this, a, b);
        }
    };
    $.fn.namespace = function(method){
        var params = Array.prototype.slice.call(arguments, 1);
        return methods[method].apply(this, params);
    };
}(jQuery));

然后您可以执行类似的操作:$('body').namespace('test', 1, 2);

更好的解决方案是只有一个主方法,并将方法名称作为字符串传递:

(function($){
    var plugin = {
        test: function (){
            console.log(this);
        },
        otherTest: function (){
            console.log(this);
        }
    };
    $.fn.namespace = function (method){
        var args = Array.prototype.slice.call(arguments, 1);
        return plugin[ method ].call(this, args);
    };
}(jQuery));

小提琴在这儿:http://jsfiddle.net/yYNDH/

最新更新