Reputation: 103
I'm wondering how I could use a syntax like $(someSelector).someObj.someMethod()
in conjunction with jQuery?
The Idea: I don't want to extend $.fn
with a bunch of custom functions. Therefore someObj
contains several methods which should resolve this
to $(someSelector)
.
I know that I could use just one custom function which execudes code depending on its argument:
(function( $ ) {
$.fn.customFunc = function( funcSelector ) {
if ( funcSelector === "do this") {
// do this
}
if ( funcSelector === "do that" ) {
// do that
}
};
}( jQuery ));
So $(someSelector).customFunc(funcSelector)
is a good workaround.
But I'm still curious: Is it possible to achieve chainability between jQuery and custom objects?
Update #1:
I like @jfriend00's approach. See his last edit. It's also based on passing the custom function name as string parameter BUT it allows defining custom functions as real functions, not some code wrapped in an if/switch statement.
Update #2:
See @barmar's custom class approach in the answers.
Upvotes: 0
Views: 372
Reputation: 103
For the sake of completeness, here's the code implementing @Barmar's suggestion:
// declare wrapper class for custom functions
function Custom() {}
// define custom functions as object methods
Custom.prototype.doThis = function() {
// do something with this.jObj
return this.jObj;
}
Custom.prototype.doThat = function() {
// do something with this.jObj
return this.jObj;
}
// use jQuery's custom function interface to initialize wrapper object
$.fn.custom = function() {
var custom = new Custom();
custom.jObj = this;
return custom;
};
// call your custom functions
$(selector).custom().doThis();
$(selector).custom().doThat();
I don't like the syntax of the call and therefore prefer @jfriend00's parameter-based solution, but if you're okay with the use of a pseudo method you have a nice wrapper class for your custom functions at hand.
Edit: Creating a Custom object on a custom() call (see @jfriend00's comment).
Upvotes: 0
Reputation: 707806
You can do something like:
$(someSelector).someObj.someMethod()
by adding a property someObj
to jQuery.fn
that is an object with it's own methods including someObj
.
jQuery.fn.someObj = {
someMethod: function() {
// method code here
}
};
But, when you do that and call it like you specified as $(someSelector).someObj.someMethod()
, the this
value in .someMethod()
will be someObj
and will NOT be the jQuery object so this is generally not a useful thing to do because you lose access to the jQuery object which is generally the reason for adding jQuery methods.
If you're concerned about adding too many methods to the jQuery namespace, then you can just use your own prefix on the method names and it will be insignificantly different from what you were asking for originally from a namespace collision point of view (this just uses a _
between parts of a single name instead of .
between two names:
$(someSelector).myUniquePrefix_add();
$(someSelector).myUniquePrefix_remove();
$(someSelector).myUniquePrefix_modify();
Any work-arounds that attempt to solve the this
issue in the first scheme are messy at best and simply not worth the trouble or the overhead because Javascript just doesn't work that way.
For example, you could make it work like this:
jQuery.fn.someObj = function(method /* other args */) {
var args = [].slice.call(arguments, 1);
return this.someObj[method].apply(this, args);
}
jQuery.fn.someObj.someMethod = function() {
// method code here
}
// and then call it like this
$(someSelector).someObj("someMethod", "arg1", "arg2");
Upvotes: 2