2013-07-17 38 views
6

只需说一下,我想将我的插件分支写一下,然后决定我想能够“命名空间”它们。到目前为止,重写$.method$.namespace.method已经很容易。如何使用NameSpace创建jQuery元素方法

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

例子:如果我叫$('body').namespace.test(),那里面方法test,我想this是件<body></body>

任何搞清楚如何退出这个功能大加赞赏的帮助。像往常一样,可能只是过度思考。

目前尝试可能的变通的类似$('body').namespace().method(),迄今为止,没有工作这么好...:P

+0

+1 - 我不认为这是可能的JavaScript。你应该在你的方法名称前加上前缀(例如'namespaceTest')。如果真正的命名空间对你来说如此重要,那么恐怕你不能使用jQuery的原型。 –

+0

我可能会忽略你的观点,但是你只是在寻找'$ .fn.myMethod(/ * function code * /);'然后你就像'$(“div”)。myMethod()'那样调用? – Archer

+1

@JosephSilber它是JavaScript!我确定有一种方法!毕竟,LoL是“最自由”的语言! – SpYk3HH

回答

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) 

Demonstration

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

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

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

+0

很好的建议,午餐后我会试试,IE8的任何想法都可以解决吗? – SpYk3HH

+0

说实话,我认为我的第二个建议,即使不是花哨的,也是最好的。 –

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/


您可以polyfill Object.keys for older browsers,或者只是手动创建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/

+0

感谢您的建议。我添加了对任何本地方法传递参数的支持:http://jsfiddle.net/WaXzL/2/ –

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

+0

,因为我的IDE中的intellisense会读取'$('ele')。namespace.method()',但它赢得'读取一个方法名称作为字符串参数传递 – SpYk3HH

+3

@ SpYk3HH:我试图保持简单。我不使用“花哨的”IDE。 –

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/

+0

这不是又一个答案吗(火箭队)? –

+1

@dystroy - 是的。在我发布之前,我去JSFiddle创建了一个小提琴,当我回来时,我没有意识到他已经发布了它。 –