Reputation: 16968
Firstly, I might be mixed up between the jQuery constructor
and init
functions, if so please ignore my terminology below.
I have an object called SineMacula
, which, at the moment is simply acting as a namespace for a library of methods.
However, I am about to write some methods for the SineMacula
object which I would like to act like jQuery extensions.
The complication arises here, instead of using the jQuery alias $
, I would like to use the SineMacula
object to run the jQuery construct. So effectively my code will look like this:
SineMacula('#test').dropdown();
instead of:
$('#test').dropdown();
However, I don't think this would be too hard if it wasn't for my next point:
I do not want to alias the whole of jQuery, I simply want the jQuery constructor to run when I call SineMacula('something')
, and then apply any methods to the result of SineMacula('something')
The best way to ask this question is by illustrating. Is the following possible?
SineMacula('#test').someFunction(function(){
// Do something here
// The jQuery object must be passed in so that
// $(this) refers to SineMacula('#test')
});
However, I do not want to be able to do this (fully alias jQuery):
SineMacula('#test').animate(); // A regular jQuery function
I am aware this is probably not possible, but felt it was worth asking :-)
Just to be clear, this is some of the code I am currently using for the SineMacula
object:
/**
* Sine Macula Javascript API
* The Sine Macula API contains all base functions for use throughout
* all websites
* @name class.sinemacula.js
* @author Ben Carey
* @version 1.0
* @date 25/10/2012
* @copyright (c) 2012 Sine Macula MMVIII Limited (sinemacula.co.uk)
*/
function SineMacula(){
// Only proceed if jQuery has been loaded
if(typeof jQuery=='undefined'){
// jQuery has not been loaded
console.log('jQuery has not been loaded');
}else{
/**
* Sine Macula Load
* Load the Sine Macula Libraries and Plugins
* into the current document
*
* The options:
* - package: the package of libraries to load
* - packageURL: a remote source to load the package details from
* - libraries: any additional libraries to load
*
* @param object options The options for the Sine Macula load
*/
this.load = function(options){
// Load Sine Macula Libraries here
}
}
};
/**
* Overlay
* Place an overlay on the page
*
* The options:
* - wrapper: the wrapper to prepend to
* - fade: indicate whether or not to fade the overlay
* - fadeSpeed: the fade speed for the overlay fade
* - opacity: the opacity to apply to the overlay
* - color: the color to apply to the overlay
* - callback: the callback to be called once the function has completed
*
* @param boolean showHide A boolean to indicate whether to show/hide the overlay
* @param object options The options for the overlay
*/
SineMacula.prototype.overlay = function (showHide,options){
// Process the overlay here
};
// All libraries are extended onto the SineMacula object
The SineMacula
object is initiated at the top of each page like so:
<script src="//libraries.example.net/jsapi" language="javascript" type="text/javascript"></script>
<script language="javascript" type="text/javascript">
var sm = new SineMacula();
sm.load();
</script>
Right, I am finding it very hard to explain what I would like to achieve. I will do my best to accomplish this below in steps, ignore the content above.
Step 1
I have a class called SineMacula
, this contains many methods that do all sorts of things. Think of it as a library like jQuery.
This is defined like so:
function SineMacula(){
// Only proceed if jQuery has been loaded
if(typeof jQuery=='undefined'){
// jQuery has not been loaded
console.log('jQuery has not been loaded');
}else{
this.load = function(options){
// Load Sine Macula Libraries here
}
}
};
Step 2
The SineMacula
class is initiated at the top of each page with the following code:
<script src="//libraries.example.net/jsapi" language="javascript" type="text/javascript"></script>
<script language="javascript" type="text/javascript">
var sm = new SineMacula();
</script>
Step 3
The SineMacula
object then loads any required libraries and extensions for the SineMacula
object by calling e.g. sm.load({package:'all'})
. This will dynamically load any extensions into the webpage.
Step 4
The extensions are defined like so:
SineMacula.prototype.doSomething = function(){
// Do something here
}
Step 5 - This is where things get a little more complex
Up until now, the SineMacula
object has been acting as a namespace for methods such as doSomething()
etc.
I would now like to define methods that do more than just act as a function.
Where I would have called SineMacula.doSomething()
, I would now like to be able to call SineMacula('#test').doSomething()
where SineMacula('#test')
acts the same as $('#test')
in jQuery.
So I can access my functions like this:
SineMacula.doSomething('maybe parameters here');
SineMacula('selector').doSomethingElse('maybe parameters here');
In the same way that you can call:
$.ajax('parameters');
$('selector').animate('parameters');
So if an argument is passed to the SineMacula
object then it is processed using the jQuery selector function and passed as the subject to the method being called.
For example:
// Call doSomethingElse on the #test element
SineMacula('#test').doSomethingElse();
// Within the doSomethingElse function $(this) relates to $('#test')
To summarise...
SineMacula('selector')
acts as $('selector')
if 'selector'
is supplied, and this gets passed to the child method. But SineMacula
is not an extension of jQuery. I do not want SineMacula
to be an Alias of $
.
Upvotes: 0
Views: 702
Reputation: 16468
if I understand the question and if you can change SineMacula
constructor
function SineMacula(){
// add following 3 lines
if(arguments.length>0) {
return jQuery.call(null,arguments);
}
// Only proceed if jQuery has been loaded
if(typeof jQuery=='undefined'){
// jQuery has not been loaded
console.log('jQuery has not been loaded');
}else{
this.load = function(options){
// Load Sine Macula Libraries here
console.log("ok load");
}
}
};
Upvotes: 1