Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create jQuery Element Methods with NameSpace

Suffice it to say, I'm wanting to branch my plugin writing a bit, and decided I want to be able to "namespace" them. So far, rewriting the $.method ones to $.namespace.method has been easy.

The problem I'm having is making Element Methods such as $('element').method(), but to use a namespace; for example $('element').namespace.method(). I've tried a few workarounds and can create $.fn.namespace.method, however, when I call this from within that method, I only get $.fn.namespace and not the 'element' that I'd like to get.

Example: If i call $('body').namespace.test(), then inside method test, I want this to be the element <body></body>

Any help figuring out how to pull this off much appreciated. Probably just over-thinking things as usual.

Currently trying possible work-arounds for something like $('body').namespace().method(), thus far, not working so well ... :P

like image 825
SpYk3HH Avatar asked Jul 17 '13 15:07

SpYk3HH


3 Answers

If you don't need to be compatible with IE8, you may use Object.defineProperty.

Working example :

 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

But I'm not convinced it's a good idea to namespace like this. I would have simply defined

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

That's what I personally do for my application specific extensions to jQuery.

like image 67
Denys Séguret Avatar answered Oct 18 '22 17:10

Denys Séguret


A better solution is to just have one main method, and pass the method name as a string:

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

Here's the fiddle: http://jsfiddle.net/yYNDH/

like image 43
Joseph Silber Avatar answered Oct 18 '22 17:10

Joseph Silber


How about instead of doing:

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

you simplify it and do

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

instead? This is much simpler:

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

Then you'd do something like: $('body').namespace('test', 1, 2);

like image 2
Rocket Hazmat Avatar answered Oct 18 '22 17:10

Rocket Hazmat