My plugin allows you to specify a callback in its options. The plugin may run before the DOM is ready, but I need to make sure the callback only runs once the DOM is ready, so I'm wrapping the callback.call()
within a $( document ).ready()
handler.
The problem is I want to maintain the plugin's context within the callback. In other words, within the callback, I want this
to be the plugin, not document
.
This is what I've come up with, but I'm not sure it's really the best way.
function MyPlugin( element, options ){
this.element = element;
this.options = $.extend( {}, defaults, options );
MyPlugin.prototype = {
functionWithCallback: function(){
if ( typeof this.options.callback == 'function' )
$( document ).ready( function( plugin ){ plugin.options.callback.call( plugin ) }( this )
}
}
}
That last line is ugly, but it allows me to pass the plugin's this
context to the callback.
I would rather do $( document ).ready( this.options.callback )
and be done with it, but then within the callback, this
is document
which doesn't really help, and doesn't necessarily give me easy access to the element the plugin was called on...
Is there a better way?
Function.prototype.call
is a perfectly solid solution for this sort of situation.
Calling functions with a different context of this
is part of what it's for.
If you'd like a more elegant but ES5 solution (so newer browsers only) you can use .bind
$(document).ready(plugin.options.callback.bind(plugin));
Bind sets a function's this
value for when you call it (as well as other parameters optionally). Here's an example of how .bind
works.
jQuery shims it with $.proxy
if you'd like to use that.
You can also do
$(plugin.options.callback.bind(plugin));