6

可以这么说,我想对我的插件进行一些分支,并决定我希望能够为它们“命名空间”。到目前为止,重写$.method那些$.namespace.method已经很容易了。

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

示例:如果我调用$('body').namespace.test(),那么在方法内部test,我想this成为元素<body></body>

任何帮助弄清楚如何解决这个问题都非常感谢。可能只是像往常一样过度思考事情。

目前正在尝试可能的解决方法,例如$('body').namespace().method(),到目前为止,效果不佳...:P

4

4 回答 4

3

如果不需要兼容 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 扩展所做的。

于 2013-07-17T15:42:13.510 回答
2

不如这样做:

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

于 2013-07-17T15:59:55.380 回答
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/

于 2013-07-17T16:05:06.360 回答
2

虽然我不推荐它,但您可以为每次调用生成一个新对象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/


您可以为旧版浏览器添加 polyfillObject.keys ,也可以手动创建methods数组。

同样适用bind:要么填充它,要么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/

于 2013-07-17T15:48:06.877 回答